SpringMVC 框架基础

是 SpringMVC

springmvcspring框架的一个模块,springmvc和spring无需通过中间层进行整合;

springmvc是一个基于MVC的web框架;

这里写图片描述

~ mvc在B/S系统下的应用

mvc是一个设计模式,mvc在B/S系统下的应用:
这里写图片描述

~ SpringMVC 框架原理

这里写图片描述

SpringMVC执行过程:

1、客户发起请求到前端控制器(DispatcherServlet);
2、前端控制器请求HandlerMapping查找Handler;可以xml配置、或注释进行查找
3、处理器映射器HandlerMapping向前端控制器返回Handler;
4、前端控制器调用处理器适配器去执行Handler;
5、处理器适配器去执行Handler;
6、Handler执行完成,给适配器返回ModelAndView;
7、处理器适配器向前端控制器返回ModelAndView;ModelAndView是SpringMVC框架的一个底层对象,包括Model和View
8、前端控制器请求视图解析器去进行试图解析;(根据逻辑视图名解析成真正的视图:jsp…)
9、视图解析器向前端控制器返回View;
10、前端控制器进行视图渲染;
11、前端控制器向用户响应结果;

SpringMVC重要组件:

1、前端控制器DispatcherServlet (不需要程序员开发)
作用:接收请求啊,响应结果;相当于转发器,中央处理器;有了DispatcherServlet减少了其他组件之间的耦合度;
2、处理器映射器HandlerMapping (不需要程序员开发)
作用:根据请求的url查找Handler;
3、处理器适配器HandlerAdapter
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler;
4、处理器Handler (需要程序员开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler;
5、视图解析器View resolver (不需要程序员开发)
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)
6、视图View (需要程序员开发jsp)
View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)

>> 入门程序:springmvc
~ 需求
以案例作为驱动:SpringMVC和mybatis使用一个案例(商品订单管理)
功能需求:商品列表查询;

~ 环境准备
1、搭建数据库,4张表:User、Orders、OrderDetail、OItems;
2、创建一个动态Javaweb项目:
3、加入需要的jar包:spring所有jar包、jstl的jar包、logging的jar包、数据库驱动包;

~ 项目结构
这里写图片描述

~ po类:User、Orders、Orderdetail、Items

// User.java
public class User {
    private Integer id;      // 用户id
    private String username; // 用户姓名
    private String sex;      // 用户性别
    private Date birthday;   // 用户生日
    private String address;  // 用户地址
}
// Orders.java
public class Orders {
    private Integer id;      // 订单id
    private Integer userId;  // 下单用户id
    private String number;   // 订单号
    private Date createtime; // 创建订单时间
    private String note;     // 备注
}
// Orderdetail.java
public class Orderdetail {
    private Integer id;
    private Integer ordersId; // 订单id
    private Integer itemsId;  // 商品id
    private Integer itemsNum; // 商品购买数量
}
// Items.java
public class Items {
    private Integer id;
    private String name;     // 商品名称
    private Float price;     // 商品定价
    private String pic;      // 商品图片
    private Date creametime; // 生产日期
    private String detail;   // 商品描述
}

~ web.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    id="WebApp_ID" version="3.1">
    <display-name>springmvc</display-name>
    
    <!-- springmvc前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- contextConfigLocation配置springmvc加载的配置文件(配置处理器映射器、适配器等)
              如果不配置contextConfigLocation,
              默认加载的是/WEB-INF/servlet名称-servlet.xml(springmvc-servlet.xml) -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
    </servlet>
    <!-- url-pattern 有3种配置方式:
         1、*.action,访问以.action为结尾的地址,由DispatcherServlet进行解析;
          2、斜杠/,所有访问的地址,都由DispatcherServlet进行解析,
                   对于静态文件的解析需要配置不让DispatcherServlet进行解析;
                   使用此种方式可以实现RESTful风格的url;
         3、/*,这样配置不对,使用这种配置,最终要转发到一个jsp页面,
                  仍然会由DispatcherServlet解析jsp地址,不能根据jsp页面找到Handler,会报错; -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>

~ springmvc.xml 文件头

// 在Beans声明处添加aop、context等命名空间的Schema定义文件的说明,这样在配置文件中就可以使用这些命名空间下的配置标签了;
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">
// -----------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd 
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd 
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd">


~ springmvc.xml 文件

// 文件头......
    <!-- 配置非注解 Handler -->
    <bean id="ItemsController1" name="/queryItems.action" 
          class="cn.itcast.ssm.controller.ItemsController1" />
    <bean id="ItemsController5" class="cn.itcast.ssm.controller.ItemsController1" />
          
    <!-- 多个映射器可以并存,前端控制器判断url能让哪些映射器去映射,就让正确的映射器处理; -->
    <!-- (1)非注解的处理器映射器:将bean的name作为url进行查找,需要在配置handler时指定beanname(就是url) 
                               在bean里面配置url -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <!-- (2)非注解的简单处理器映射器:简单url映射;   将url和handler集中进行配置; -->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>  <!-- 同一个bean可以有多个url -->
                <!-- 对ItemsController1进行url映射,url是/queryItems1.action -->
                <prop key="/queryItems1.action">ItemsController1</prop>
                <prop key="/queryItems2.action">ItemsController1</prop>
                <prop key="/queryItems5.action">ItemsController5</prop>
            </props>
        </property>
    </bean>
    
    <!-- (1)非注解的处理器适配器1:所有处理器适配器都实现HandlerAdapter接口;
                     要求:handler实现Controller接口; -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
    <!-- (2)非注解的处理器适配器2:所有处理器适配器都实现HandlerAdapter接口;
                     要求:handler实现HttpRequestHandler接口; -->
    <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
    
推荐使用下面这种情况:

    <!-- (3)对于注解的Handler可单独配置(不需要写id、name);  
         实际开发中建议使用组件扫描;可扫描controller、service、...... -->
    <!-- <bean class="cn.itcast.ssm.controller.ItemsController3" /> -->
    <context:component-scan base-package="cn.itcast.ssm.controller"></context:component-scan> 配置注解的handler
    

    <!-- (3)注意:注解的映射器和适配器必须配对使用! -->
    <!-- (3)注解的映射器 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
    <!-- (3)注解的适配器 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />


    <!-- 使用mvc:annotation-driven代替上边的注解映射器和注解适配器配置;
         mvc:annotation-driven默认加载很多的参数绑定方法,比如json转换解析器就默认加载了,
           如果使用mvc:annotation-driven就不用再配置
           上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter了;
           实际开发中使用mvc:annotation-driven -->
    <!-- <mvc:annotation-driven></mvc:annotation-driven> --> 配置MVC注解驱动
    
    <!-- 视图解析器:解析jsp页面,默认使用jstl标签,classpath系需要有jstl的jar包 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

~ Handler - ItemsController1.java

public class ItemsController1 implements Controller { // 实现Controller接口的处理器 ,根据配置是不使用注解方式

    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 调用service查找数据库,查询商品列表,这里使用静态数据模拟;
        List<Items> itemsList = new ArrayList<Items>();
        Items items1 = new Items(); // 向List中填充静态数据;
        items1.setName("联想笔记本");
        items1.setPrice(6000f);
        items1.setDetail("我的联想笔记本");
        Items items2 = new Items();
        items2.setName("小米手机");
        items2.setPrice(2000f);
        items2.setDetail("我的小米手机");
        itemsList.add(items1);
        itemsList.add(items2);

        // 返回ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        // 相当于request的setAttribute,在jsp页面中通过itemsList取数据
        modelAndView.addObject("itemsList", itemsList);
        // 指定视图
        // modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
        modelAndView.setViewName("/items/itemsList");
        return modelAndView;
    }
}

~ Handler - ItemsController2.java

public class ItemsController2 implements HttpRequestHandler{
    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Items> itemsList = new ArrayList<Items>(); //........造数据
        // 设置视图模型
        request.setAttribute("itemsList", itemsList);
        // 设置转发的视图
        request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response);
        // 使用此方法可以通过修改response,设置响应的数据格式,比如响应json数据;
        // response.setCharacterEncoding("utf-8");
        // response.setContentType("application/json;charset=utf-8");
        // response.getWriter().write("json串");
    }
}

~ Handler - ItemsController3.java

@Controller  // 使用Controllerz注释标识它是一个控制器
public class ItemsController3 { // 注解开发Handler
    // 方法1:查询商品列表
    // @RequestMapping实现对queryItemsAnnotation方法和url进行映射,一个方法对应一个url
    // 一般建议方法名和url写成一样;
    @RequestMapping("queryItemsAnnotation")
    public ModelAndView queryItemsAnnotation() throws Exception {
        List<Items> itemsList = new ArrayList<Items>();
        Items items1 = new Items(); // 向List中填充静态数据;
        items1.setName("联想笔记本");
        items1.setPrice(6000f);
        items1.setDetail("我的联想笔记本");
        Items items2 = new Items();
        items2.setName("小米手机");
        items2.setPrice(2000f);
        items2.setDetail("我的小米手机");
        itemsList.add(items1);
        itemsList.add(items2);
        // 返回ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        // 相当于request的setAttribute,在jsp页面中通过itemsList取数据
        modelAndView.addObject("itemsList", itemsList);
        // 返回ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        // 相当于request的setAttribute,在jsp页面中通过itemsList取数据
        modelAndView.addObject("itemsList", itemsList);
        // 指定视图
        // 下边的路径,如果在视图解析器中配置jsp路径的前缀和jsp路径的后缀,
        // 上边的路径配置可以不在程序中指定jsp路径的前缀和jsp路径的后缀;
        // modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
        modelAndView.setViewName("items/itemsList");
        return modelAndView;
    }
    // 方法2:添加商品......
}


~ itemsList.jsp

~ itemsList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>查询商品列表</title>
    </head>
<body>
    <form action="${pageContext.request.contextPath}/item/queryItem.action" method="post">
        查询条件:<table width="100%" border="1">
                <tr><td><input type="submit" value="查询" /></td></tr>
            </table>
        商品列表:<table width="100%" border="1">
                <tr><td>商品名称</td>
                    <td>商品价格</td>
                    <td>生产日期</td>
                    <td>商品描述</td>
                    <td>操作</td> </tr>
                <c:forEach items="${itemsList}" var="item">
                    <tr> <td>${item.name}</td>
                         <td>${item.price}</td>
                         <td><fmt:formatDate value="${item.creametime}" pattern="yyyy-MM-dd HH:mm:ss" /></td>
                        <td>${item.detail}</td>
                        <td><ahref="${pageContext.request.contextPath}/item/queryItem.action?id=${item.id}}">修改</a></td>
                    </tr>
                </c:forEach>
            </table>
    </form>
</body>
</html>

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

~ SpringMVC开发步骤

1、在 web.xml 文件中配置前端控制器:

这里写图片描述

2、在 springmvc.xml 文件中配置处理器适配器:
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
通过查看源代码,可以看出此适配器能执行实现Controller接口的Handler;
这里写图片描述

3、开发ItemsController1.java:**Handler需要实现Controller接口,才能由org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter适配器执行;
4、编写itemsList.jsp:
5、配置Handler:将编写的Handler在spring容器中加载
<bean name="/queryItems.action" class="cn.itcast.ssm.controller.ItemsController1" />
6、在 springmvc.xml 文件中配置处理器映射器:
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
7、springmvc.xml 文件中配置视图解析器:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
8、部署调试:访问地址:http://localhost:8080/springmvc/queryItems.action
注意:启动程序的时候使用debug模式,不使用start启动;debug方式启动代码才能实现修改代码时不加方法、参数,不用重启Tomcat,这个叫做热部署,debug才支持热部署;

~ 非注解的处理器映射器

多个映射器可以并存,前端控制器判断url能让哪些映射器去映射,就让正确的映射器处理;
(1)class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"
(2)class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"

~ 非注解的处理器适配器

(1)class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"
要求:handler实现Controller接口;
(2)class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"
要求:handler实现HttpRequestHandler接口;

 

>>>>再次上面的处理器映射器和处理器适配器可以不配对使用

~ 注解的映射器和适配器

配置

(除了使用MVC 注解驱动以外,处理器映射器和处理器适配器必须成对使用, 注意:下面图MVC:annotation-driven应该关闭才对)

这里写图片描述

注解开发Handler:
这里写图片描述

在Spring容器中加载Handler: 使用组件扫描
这里写图片描述

  • **部署调试:**访问地址:http://localhost:8080/springmvc/queryItemsAnnotation.action

~ 视图解析器前缀和后缀

这里写图片描述

~ 源码分析

  • 1、从web.xml文件中进入前端控制器,通过前端控制器源码,分析springmvc的执行过程:
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  • 2、前端控制器接收请求,调用doDispatch()方法:这里写图片描述
  • 3、前端控制器调用处理器映射器查找Handler:映射器根据request中的url找到了Handler,最后返回一个在执行器链,链里面包含Handler;
  • 这里写图片描述
  • 4、调用处理器适配器去执行Handler,得到执行的结果ModelAndView:
  • 这里写图片描述
  • 5、视图渲染,将Model的数据填充到request域:
    这里写图片描述
发布了25 篇原创文章 · 获赞 23 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/lyfqyr/article/details/83900067
今日推荐