Spring MVC基础

  • Spring MVC是基于Model 2实现的技术框架,Model 2是经典的MVC模型在web应用中的变体。
  • model 1的开发模式是:jsp+javabean的模式,它的核心是jsp页面。
  • model 2的开发模式是:jsp+servlet+javabean的模式。

一、运行原理

  • 用户发起请求后,由前端控制器DispatcherServlet接受用户请求响应
  • 然后前端可控制性请求查找Handler,处理器映射器HandleMapper收到请求后通过xml或者注解,根据url找到对应的Handler(也就是Controller),找到之后前端控制器请求处理器适配器去执行Handler
  • 处理器适配器调用处理器Handler的方法执行,返回ModelAndView
  • 处理器适配器拿到ModelAndView后返回给前端控制器,前端控制器拿到ModelAndView后请求视图解析器去解析
  • 解析完成之后将View返回给前端控制器,前端控制器将View进行渲染之后展示给用户。
    • MVC.png
  • DispatcherServlet:作为前端控制器,整个流程控制的中心,控制其它组件执行, 统一调度,降低组件之间的耦合性,提高每个组件的扩展性。
  • HandlerMapping:通过扩展处理器映射器实现不同的映射方式,例如:配置文件 方式,实现接口方式,注解方式等。
  • HandlerAdapter:通过扩展处理器适配器,支持更多类型的处理器,调用处理器传 递参数等工作。
  • ViewResolver:通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、 freemarker、pdf、excel等。

二、开发步骤

1、引入依赖

  • 添加依赖spring-webmvc,添加依赖后会添加八个jar包:
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.2.RELEASE</version>
    </dependency>
    

2、配置web.xml

  • 在web.xml中配置一个servlet与对应的类:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
             http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
        <servlet>
            <servlet-name>dispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-mvc.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>dispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    
  • 配置web.xml文件: 让所的/请求都交给DispatcherServlet,而DispatcherServlet里面需要配置一个contextConfigLocation,上下文配置路径,也就是SpringMVC的配置文件。如果没有显式地配置该属性,SpringMVC会在默认WEB-INF下去找[servlet-name]-servlet.xml文件

3、配置Spring MVC配置文件

  • 有两种实现方式,一种是实现接口的方式,另一种是使用注解的方式。

  • 实现接口:

    • 第一个bean配置视图解析器,可以分别分别指定前缀与后缀,在虚拟视图前与后拼接字符串,去请求指定的资源。
    • 第二个与第三个bean配置servlet,当用户请求指定url的时候就是去请求这个对应的类。使用name而不是id是因为id不能包含特殊字符。
    • 最后一个mvc标签设置了默认的servlet-handler,用于请求静态资源。
      <?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"
             xsi:schemaLocation="http://www.springframework.org/schema/beans 
             http://www.springframework.org/schema/beans/spring-beans.xsd 
             http://www.springframework.org/schema/mvc 
             https://www.springframework.org/schema/mvc/spring-mvc.xsd">
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <property name="prefix" value="/WEB-INF/view/"/>
              <property name="suffix" value=".jsp"/>
          </bean>
          <bean name="/ProductInput" class="com.controller.ProductInputController"/>
          <bean name="/ProductDetail" class="com.controller.ProductDetailController"/>
          <mvc:default-servlet-handler />
      </beans>
      
  • 配置SpringMVC的视图解析器:可以分别指定前缀和后缀

    • prefix:控制器会在虚拟视图前拼接该字符串
    • suffix:控制器会在虚拟视图后拼接该字符串
  • 使用注解:

    <?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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd 
           http://www.springframework.org/schema/mvc 
           https://www.springframework.org/schema/mvc/spring-mvc.xsd 
           http://www.springframework.org/schema/context 
           https://www.springframework.org/schema/context/spring-context.xsd">
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/view/"/>
        </bean>
        <context:component-scan base-package="com.innovation"/>
        <mvc:default-servlet-handler />
        <mvc:annotation-driven/>
    </beans>
    
  • 最后一个标签指定使用注解,如果不加就扫描不到,访问非静态资源时就会出现404.

4、创建controller包及控制类

  • 实现接口

    public class ProductDetailController implements Controller {
        @Override
        public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
            String spid = httpServletRequest.getParameter("pid");
            String pname = httpServletRequest.getParameter("pname");
            String sprice = httpServletRequest.getParameter("price");
            String image = httpServletRequest.getParameter("image");
            int pid = spid == null||"".equals(spid.trim())?0:Integer.parseInt(spid);
            double price = sprice == null||"".equals(sprice.trim())?0.0:Double.parseDouble(sprice);
            Product p = new Product(pid,pname,price,image);
            //返回viewName,将对象与对象名放入request域中
            return new ModelAndView("product","product",p);
        }
    }
    
  • 创建的新的controller类需要实现Controller接口然后重写handleRequest方法,这个方法接收HttpServletRequest与HttpServletResponse参数,返回一个ModelAndView,这个ModelAndView对象可以放需要转发到的虚拟的视图,还可以向request域中添加属性。

  • 使用注解:

    @Controller
    public class EmployeeController {
          private IEmployeeService service = new EmployeeServiceImpl();
          @RequestMapping("/employees")
          public String getEmployeesPage(Model model){
              List<Employee> list = service.getAllEmployees();
              model.addAttribute("list",list);
              return "employees.jsp";
          }
          @RequestMapping("/employeeInfo")
          public String getEmployById(HttpServletRequest request,Model model){
              String eid = request.getParameter("eid");
              int id = eid==null?-1:Integer.parseInt(eid);
              Employee e = service.getEmployeeById(id);
              model.addAttribute("employee",e);
              return "employeeInfo.jsp";
          }
    }
    
  • 使用注解的方式更为简单,只需要在类名前加上@Controller,这样在包扫描的时候就会扫描到,然后再每个方法前加上@RequestMapping注解,用于指定匹配的url,这个url必须全局唯一。

  • 每个方法可以添加参数,也可以不加参数,既可以加一个参数,也可以加两个参数,Model、HttpSession、HttpServletRequest等类型的参数都可以作为形参。上面的两个方法返回值都是字符串,指定需要转发的页面。

  • 常用内置对象

    • strings:字符串格式化方法,常用的Java方法它都有。比如:equals,equalsIgnoreCase,length, trim, toUpperCase,toLowerCase,indexOf,substring,replace,startsWith,endsWith,contains, containsIgnoreCase等。
    • numbers:数值格式化方法,常用的方法有:formatDecimal等。
    • bools:布尔方法,常用的方法有:isTrue,isFalse等。
    • arrays:数组方法,常用的方法有:toArray,length,isEmpty,contains,containsAll等。
    • lists,sets:集合方法,常用的方法有:toList,size,isEmpty,contains,containsAll,sort等。
    • maps:对象方法,常用的方法有:size,isEmpty,containsKey,containsValue等。
    • dates:日期方法,常用的方法有:format,year,month,hour,createNow等。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343