SpringMVC框架整理

Posted Nothing_doit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC框架整理相关的知识,希望对你有一定的参考价值。

博客主要对SpringMVC框架的知识点进行整理,该篇介绍了SpringMVC的HelloWorld环境搭建,常用注解的使用,Ant路径风格,RestFul编程风格,最后使用SpringMVC实现一个RestFul编程风格的CRUD。



MVC概述

     Model(模型)-View(视图)-Controller(控制器)      Model(模型):              业务模型:业务流程和业务逻辑              数据模型:页面显示的数据.数据库保存的数据对应的javaBean      View(视图):和用户直接交互的页面、程序界面      Controller(控制器):调度器控制整个网站的转发逻辑

SringMVC概述

     SpringMVC是基于MVC理念的表现层框架,是目前最主流的MVC框架。       Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口。       支持 REST 风格的 URL 请求 采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性


SpringMVC运行流程

SpringMVC的运行逻辑:

        ①客户端请求提交到DispatcherServlet(SpringMVC前端控制器)       ②由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller。           根据 HandlerMapping提供的信息,再去找到能真正解析和调用业务逻辑方法的适配器。       ③DispatcherServlet将请求提交到Controller(也称为Handler),也就是使用适配器去执行目标方法           mv = ha.handle(processedRequest, response, mappedHandler.getHandler());       ④Controller调用业务逻辑处理后,返回ModelAndView           ModelAndView包含了要去向视图的信息,以及其他信息       ⑤ DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图           ViewResoler进行视图解析,调用render.解析出去哪个页面       ⑥视图负责将结果显示到客户端,渲染            RequestDispatcher rd            rd.forward(requestToExpose, response);  总结:请求到达-->找到能够执行目标方法的适配器--->执行目标方法--->返回视图信息以及数据信息(MV)--->根据返回信息渲染视图--->展示视图

HelloWorld环境搭建


①导入jar包      Spring基础包 com.springsource.net.sf.cglib-2.2.0.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar commons-logging-1.1.3.jar spring-aop-4.0.0.RELEASE.jar spring-aspects-4.0.0.RELEASE.jar spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0.RELEASE.jar spring-core-4.0.0.RELEASE.jar spring-expression-4.0.0.RELEASE.jar
     SpringMVC需要的包 spring-web-4.0.0.RELEASE.jar spring-webmvc-4.0.0.RELEASE.jar
②在web.xml中配置前端控制器 <!--SpringMVC的前端控制器,它是一个真实的Servlet继承于HttpServlet     因此配置和Servlet配置基本一致 --> <!-- The front controller of this Spring Web application, responsible for handling all application requests -->     <servlet>         <servlet-name>springDispatcherServlet</servlet-name>         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>         <init-param>             <param-name>contextConfigLocation</param-name>             <!--这个location写SpringMVC配置文件的-->              <param-value>location</param-value>         </init-param>         <!--这个是启动的优先级,数值越小,优先级越高-->         <load-on-startup>1</load-on-startup>     </servlet>      <!--配置拦截那些请求-->     <!-- Map all requests to the DispatcherServlet for handling -->     <servlet-mapping>         <servlet-name>springDispatcherServlet</servlet-name>         <!--这里配置成/,可以拦截所有请求同时又覆盖了DefaultServlet的配置,这样所有的请求都由我们的前端控制器拦截          同时也体现了RestFul风格编程          -->          <url-pattern>/</url-pattern>     </servlet-mapping>        创建springmvc配置文件,并将配置文件的地址写到location            src目录下新建
              配置location(classpath表示在类路径下) <param-value>classpath:springmvc.xml</param-value>      这样基础的环境就搭建好了。
  ④编写一个简单的请求响应流程,测试运行环境                ①index.jsp(请求/hello)            <h1 align="center"><a href="$pageContext.request.contextPath /hello">Hello</a></h1>                                 ②编写一个handle处理这个请求 package com.springmvc.handle;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; //基于注解注入,需要加入相关注解 @Controller public class MyHandle     //映射请求地址     @RequestMapping(" /hello ")     public String hello()         System.out.println("接收到请求");         return "success";                 ③配置SpringMVC框架,让框架帮忙处理请求(springmvc.xml) <?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: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/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <!-- 开启包的自动扫描,将加了controller注解的handle类注入 -->     < context:component-scan base-package="com.springmvc.handle"></context:component-scan>     <!-- 配置视图解析器,用于渲染mv -->     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">         <!-- 给返回地址配置一个前缀 -->         <property name="prefix" value="/"></property>         <!-- 配置一个后缀 -->         <property name="suffix" value=".jsp"></property>         <!--/success.jsp(前缀+返回结果+后缀共同构成转发地址)-->     </bean>
</beans>                ④编写响应页面success.jsp <h1>HelloWorld运行环境配置成功</h1>                ⑤运行测试

@RequestMapping

      ① 在类上标注,表示该类中的所有handle方法都以这个映射地址开始。 相对于 WEB 应用的根目录       ② 在方法上标注,若类上没有@RequestMapping,直接表示请求地址,若类上有,类上映射+方法上映射共同构成请求地址。 相对于标记在类上的URL
      作用:DispatcherServlet 截获请求后,就通过控制器上@RequestMapping 提供的映射信息确定请求所对应的处理方法。               属性:       value:设置请求地址,在类上标注和在方法上标注/表示的含义不同       method:设置某个方法处理什么样的请求,method是个数组表示可以处理多个符合要求的请求。默认可以处理任意请求       params:设置请求参数(可以设置多个请求参数)(支持简单的表达式)           当配置了params时,必须在请求的时候传入配置的参数,不匹配或者不传都会报错404           当设置多个请求参数的时候必须都设置,否则报错404           结论:params设置的请求参数必须精确匹配,否则报错 params = !user 表示请求参数不能设置为user,其他的都可以 params = user!=1 表示请求参数值不能等于1
含有params的代码:     /**      * 这个请求地址中必须有password,user可以有可以没有,但是若有user的值不能是1,不能有username      * 还可以有其他请求      * @return      */     @RequestMapping(value="/test5", params="user!=1", "password", "!username")     public String test5()         System.out.println("接受到请求");         return "success";                 headers设置请求头           发送请求的请求头必须包含headers中的内容,不同的浏览器请求头不同,可以用于区分不同的浏览器     /**      * headers (设置只有某一浏览器可以访问)      * @return      */     @RequestMapping(value="/testheader", headers="User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0")     public String test6()         System.out.println("接受到请求");         return "success";     
   设置@RequestMapping的条件后,在发送请求的时候,必须满足上边的所有规则,否则报错,什么也不写表示默认规则。
   return String 转发地址,在springmvc配置文件中配置的视图解析器还会对这个地址进行包装 

  Ant路径风格

   ? : 表示匹配任意一个字符    * : 表示匹配任意零个或者多个字符    ** : 表示多层模糊匹配 (要使用**多层模糊匹配要把这两个**包起来)(这样就可以在具体路径之前写多层嵌套路径)      匹配原则:当都是模糊匹配的时候,先精确再模糊,先范围大的再范围小的
     示例:      Ant路径:/user/*/createUser:             匹配/user/aaa/createUser、/user/bbb/createUser等URL                  /user/**/createUser:            匹配 /user/createUser、/user/aaa/bbb/createUser 等 URL                   /user/createUser??:           匹配 /user/createUseraa、/user/createUserbb 等 URL
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;
@Controller public class AntUrlPathHandle     /**      * ant路径风格      *      ?:表示匹配任意一个字符      *      *:表示匹配任意零个或者多个字符      *      **:表示多层模糊匹配 (要使用**多层模糊匹配要把这两个**包起来)      *      *      当都是模糊匹配的时候,先精确在模糊,先范围大的再范围小的      * @return      */     @RequestMapping(value="/??ervice")     public String test2()         System.out.println("接收到请求地址是模糊匹配?的请求");         return "success";          @RequestMapping(value="/*ervice")     public String test3()         System.out.println("接收到请求地址是模糊匹配*的请求");         return "success";          @RequestMapping(value="/*/*ervice")     public String test5()         System.out.println("接收到请求地址是模糊匹配一层*的请求");         return "success";          @RequestMapping(value="/**/ervice")     public String test4()         System.out.println("接收到请求地址是模糊匹配**多层模糊的请求");         return "success";     

RestFul编程风格

   简介:      REST:即 Representational State Transfer。 (资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用       资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它, 每种资源对应一个特定的 URI。要获取这个资源,访问它的URI就可以, 因此 URI 即为每一个资源的独一无二的识别符       表现层(Representation)把资源具体呈现出来的形式,叫做它的表现层(Representation)比如,文本可以用 txt 格式表现,也可以用 html 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。       状态转化(State Transfer)每发出一个请求,就代表了客户端和服务器的一次交互过程HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。 体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
    原生web项目的订单处理的路径       /order/delete?id=1       /order/update?id=1       /order/save      /order/get?id=1          RestFul编程风格      order/1 GET 查询1号订单      order/1 DELETE 删除1号订单      order/1 PUT 更新1号订单      order POST 保存一个订单      每一个路径orderHandle只能占一层路径,而且必须有
     RestFul本质就是充分利用Http协议中定义了很多请求方式。有了这个支持。地址还是不变。不同的请求方式就代表当前资源不同的状态转化(删除?修改?保存?....)数据都放在请求体中,不放在地址栏后
@PathVariable 映射 URL 绑定的占位符      带占位符的 URL 是 Spring3.0 新增的功能,该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义      通过@PathVariable 可以将 URL中占位符参数绑定到控制器处理方法的入参中:URL 中的 xxx 占位符可以通过 @PathVariable("xxx") 绑定到操作方法的入参中。
这样在@RequestMapping配置的映射地址设置占位符,同时使用@PathVariable注解可以获取到
HiddenHttpMethodFilter:浏览器 form 表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不支持, Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与 DELETE 请求。          原生的jsp页面无法发送DELETE请求和PUT请求,要想发送需要在web.xml中进行配置         <!-- 配置配置org.springframework.web.filter.HiddenHttpMethodFilter来支持页面发起restful请求 PUT、DELETE -->     <filter>         <filter-name>HiddenHttpMethodFilter</filter-name>         <filter-class>org.springframework.web.filter. HiddenHttpMethodFilter </filter-class>     </filter>     <filter-mapping>         <filter-name>HiddenHttpMethodFilter</filter-name>         <servlet-name>springDispatcherServlet</servlet-name>     </filter-mapping>
写一个简易的RestFul风格的程序                orderManage.jsp <%@ page language="java" contentType="text/html; charset=UTF-8"     pageEncoding="UTF-8"%> <!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>Insert title here</title> </head> <body>     <h1>订单管理</h1>     <!-- get请求获取订单 -->     <a href="/myspringmvc01 /order/1">获取一个订单</a>     <br>     <!-- post请求添加订单 -->     <form action="/myspringmvc01/order" method="post" >         <input type="submit" value="新增一个订单">     </form>     <br>     <!-- PUT请求修改订单 -->     <form action="/myspringmvc01/order/1" method="post" >         <input type="hidden" name="_method" value="PUT" >         <input type="submit" value="修改一个订单">     </form>     <br>     <!-- DELETE请求删除订单 -->     <form action="/myspringmvc01/order/1" method="post" >         <input type="hidden" name="_method" value="DELETE" >         <input type="submit" value="删除一个订单">     </form> </body> </html>
            处理请求的handle方法 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod;
@Controller public class RestFulPathHandle     /**      *  订单处理      *  order 1 GET 获取订单号为1的订单      *  order 1 DELETE 删除订单号为1的订单      *  order 1 PUT 更新订单号为1的订单      *  order   POST 新增订单      * RestFul 利用Http协议中的多种请求方式实现状态转换      * 通过判断提交的请求类型来选择执行不同的处理请求的方法      * 路径,请求参数只能表示一层路径,必须得有      * 利用@PathVariable注解从url中获取值给参数赋值      */     @RequestMapping(value="/order/ id",method=RequestMethod.GET)     public String getOrder(@PathVariable(" id")String id)         System.out.println("获取订单号为" + id + "的订单");         return "success";          @RequestMapping( value="/order" ,method=RequestMethod.POST)     public String saveOrder()         System.out.println("新增一个订单");         return "success";          @RequestMapping( value="/order/id" ,method=RequestMethod.PUT)     public String updateOrder(@PathVariable( "id" )String id)         System.out.println("更新订单号为" + id + "的订单");         return "success";          @RequestMapping( value="/order/id" ,method=RequestMethod.DELETE)     public String deleteOrder(@PathVariable( "id" )String id)         System.out.println("删除订单号为" + id + "的订单");         return "success";     

请求数据传入(请求方法签名处理)

     Spring MVC 通过分析处理方法的签名,将 HTTP 请求信息绑定到处理方法的相应人参中。 Spring MVC 对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。 必要时可以对方法及方法入参标注相应的注解( @PathVariable 、@RequestParam、@RequestHeader 等)、Spring MVC 框架会将 HTTP 请求的信息绑定到相应的方法入参中,并根据方法的返回值类型做出相应的后续处理。
在原生web中获取请求参数值的时候      例如:      请求参数:username=admin 其中username相当于请求参数的键,admin相当于请求参数的值      我们在servlet中获取的时候是,request.getParameter("username")拿到admin      在SpringMVC中类似并且更为简单 获取请求参数的方式       ①直接在方法的参数列表处,声明一个(保存请求参数值的)参数(入参)           若不使用@RequestParam注解,参数名就是请求参数的键(相当于getParameter("键")),key=参数名           在发送请求的时候,不传入任何值,或者键不匹配,key(参数名)=null(value=null)           键匹配不传值,值为空串。           可以传入多个键值对。                 使用@RequestParam注解(使用注解匹配,注解的value值是键)可以传入多个键值对           属性:           value 默认空串(设置键)           required 默认true (就是必须传参数与这个键匹配的键值对,不传,或者不匹配都会400)           defaultValue 默认没有,用于设置默认值(键的默认值)           设置默认值后,required=false,可以不传这个键值对           当获取多个请求参数键值对,SpringMVC框架可以自动匹配,赋值      注:当不使用注解,参数名就是键,SpringMVC根据参数名获取到对应的值并赋值给这个参数      使用注解,注解的value值是键,根据键获取对应的值,赋值给这个参数                      不使用@RequestParam     @RequestMapping(value="/testparam")     public String testParam(String username)         //这样就可以拿到传入的username的值         System.out.println("username=" + username);         return "success";     
          使用@RequestParam     @RequestMapping(value="/testrequestparam")     public String testParam2(@RequestParam(value="user",defaultValue="default")String username, String password)         System.out.println("username=" + username);         System.out.println("password=" + password);         return "success";     
      ②还可以使用@PathVariable,@RequestHeader,@CookieValue对入参进行修饰      请求头包含了若干个属性,服务器可据此获知客户端的信息,通过 @RequestHeader 即可将请求头中的属性值绑定到处理方法的入参中
          @RequestHeader修饰入参(将请求头中的某些值和入参进行绑定)   /**      * 入参与请求头中的键值对(任意的)进行绑定      * @RequestHeader   value=key(将入参(参数列表处设置的参数)和请求头中key对应的值绑定)      * 这些注解的属性和@RequestParam注解属性一致,含义一致      */     @RequestMapping(value="/testheader")     public String testHeader(@RequestHeader(value="User-Agent")String agent)         System.out.println("Agent=" + agent);         return "success";          @RequestMapping(value="/testheader2")     public String testHeader2(@RequestHeader(value="Accept-Language")String language)         System.out.println("Accept-Language=" + language);         return "success";     
        @CookieValue修饰入参(将Cookie值与入参进行绑定)     /**      * 使用@RequestHeader获取Cookie,在第一次请求的时候会报500错,因为第一次请求时没有Cookie      *  Missing header 'Cookie' of type [java.lang.String]找不见Cookie      * 获取Cookie使用@CookieValue注解获取(设置defaultValue=""就不会出现500错),Cookie值为空串      *          还可以获取JSESSIONID      * @param cookie      * @return      */     @RequestMapping(value="/testcookie")     public String testCookie(@CookieValue(value="Cookie", defaultValue="")String cookie)         System.out.println("Cookie=" + cookie);         return "success";          @RequestMapping(value="/testcookie2")     public String testCookie2(@CookieValue(value="JSESSIONID",defaultValue="")String JSESSIONID)         System.out.println("JSESSIONID=" + JSESSIONID);         return "success";                   使用 POJO 对象绑定请求参数值            使用表单提交数据,Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。
      测试:           POJO类 Employee类 public class Employee
    private Integer id;     private String name;     private Integer age;     private Address address;     public Employee()         super();          public Employee(Integer id, String name, Integer age, Address address)         super();         this.id = id;         this.name = name;         this.age = age;         this.address = address;          public Integer getId()         return id;          public void setId(Integer id)         this.id = id;          public String getName()         return name;          public void setName(String name)         this.name = name;          public Integer getAge()         return age;          public void setAge(Integer age)         this.age = age;          public Address getAddress()         return address;          public void setAddress(Address address)         this.address = address;          @Override     public String toString()         return "Employee [id=" + id + ", name=" + name + ", age=" + age                 + ", address=" + address + "]";     
       Address public class Address     private String city;     private String street;     public Address()         super();          public Address(String city, String street)         super();         this.city = city;         this.street = street;          public String getCity()         return city;          public void setCity(String city)         this.city = city;          public String getStreet()         return street;          public void setStreet(String street)         this.street = street;          @Override     public String toString()         return "Address [city=" + city + ", street=" + street + "]";               表单:     <form action="/myspringmvc02/testpojo" method="post">         name<input type="text" name="name"><br>         age<input type="text" name="age"><br>         address.city<input type="text" name="address.city"><br>         address.street<input type="text" name="address.street"><br>         <input type="submit" value="提交">     </form>                  处理请求的方法:    /**      * SpringMVC框架也可以自动处理POJO(JavaBean对象)      * 只需要让表单的属性和POJO属性一一对象,然后在方法参数列表设置一个对象引用保存这个对象,      * 入参设置为一个对象SpringMVC框架在处理这个方法的时候会帮你自动封装,级联属性也可以自动封装      *      * 根据表单给的属性值,自动封装成对象     */     @RequestMapping(value="/testpojo")     public String testPOJO(Employee employee)         System.out.println(employee);         return "success";      解决POST中文乱码问题 乱码:         请求乱码:            post请求 (原生解决方式)在服务器第一次接收到请求的时候(在filter中设置)                 request.setCharacterEncoding("utf-8")            get请求 服务器的server.xml中设置                 URIEncoding="UTF-8" (8080端口号设置的那里,大小写都行)        响应乱码:           response响应的时候乱码(将数据从服务器发送到浏览器的时候乱码)           response.setContentType("text/html;charset=UTF-8");
       SpringMVC框架的乱码问题解决方式:      get请求和原生的解决方式一致      post请求
               web.xml中配置CharacterEncodingFilter   <filter>      <filter-name>characterEncodingFilter</filter-name>      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>      <!-- 配置编码参数 -->      <init-param>      <!-- 配置请求编码设置 -->           <param-name>encoding</param-name>           <param-value>UTF-8</param-value>      </init-param>      <init-param>      <!-- 配置响应编码设置 设置的时候根据请求编码的参数设置-->           <param-name>forceEncoding</param-name>           <param-value>true</param-value>      </init-param> </filter> <filter-mapping>      <filter-name>characterEncodingFilter</filter-name>      <!-- 对所有请求和.jsp进行拦截 -->      <url-pattern>/*</url-pattern> </filter-mapping>
注意:       当使用框架提供的响应方式的时候,SpringMVC自动的配置好请求和响应编码        若使用原生的响应,需要配置编码的text/html(utf-8已经帮你设置)
使用原生的ServletAPI作为入参       使用原生的ServletAPI作为入参,这些原生的东西,在想要用的时候,只需要在入参处设置即可,SpringMVC框架会给你准备好       HttpServletRequest       HttpServletResponse       HttpSession       java.security.Principal       Locale       InputStream      OutputStream      Reader      Writer /**      * 响应的编码测试      * 使用SpringMVC框架的一个好处就是在想要用的时候直接声明一个变量保存就好      * 想要使用原生的api只需要在参数列表设置就行      * @param employee      * @return      */     @RequestMapping(value="/testpon")     public void testResponse(HttpServletRequest request, HttpServletResponse response)         System.out.println("使用原生的api不需要设置返回值");         System.out.println("param:" + request.getParameter("user"));         try             /*              * 只有使用原生api,CharacterEncodingFilter会出现乱码,原因ÿ

以上是关于SpringMVC框架整理的主要内容,如果未能解决你的问题,请参考以下文章

myBatis+Spring+SpringMVC框架面试题整理

SpringMVC的一个小整理

Spring和springMVC详细示例精通教程

SpringMVC

框架合集SpringMVC教程汇总

springmvc简介