• 1.SpringMVC概述
• 2.SpringMVC的HelloWorld
• 3.使用@RequestMapping映射请求
• 4.映射请求参数&请求头
• 5.处理模型数据
• 6.视图和视图解析器
• 7.RESTful CRUD
• 8.SpringMVC表单标签&处理静态资源
• 9.数据转换&数据格式化&数据校验
• 10.处理JSON:使用HttpMessageConverter
• 11.国际化
• 12.文件的上传
• 13.使用拦截器
• 14.异常处理
• 15.SpringMVC运行流程
• 16.在Spring的环境下使用SpringMVC
• 17.SpringMVC对比Struts2
 
 
 
1.SpringMVC概述
      • Spring为展现层提供的基于MVC设计理念的优秀的Web框架,是目前最主流的MVC框架之一
      • Spring3.0后全面超越Struts2,成为最优秀的MVC框架
      • Spring MVC通过一套MVC注解,让POJO成为处理请求的控制器,而无须实现任何接口。
      • 支持REST风格的URL请求
      • 采用了松散耦合可插拔组件结构,比其他MVC框架更具扩展性和灵活性
 
 
 

2.HelloWorld

 ❤ 

 
      –

加入
jar
       –

web.xml
中配置
DispatcherServlet
       –

加入
Spring MVC
的配置文件
       –

求的
理器,并
标识为处
理器
       –

视图
 ❤  jar
       – commons-logging-1.1.3.jar
       – spring-aop-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
       – spring-web-4.0.0.RELEASE.jar
       – spring-webmvc-4.0.0.RELEASE.jar
 
 ❤  在web.xml中配置DispatcherServlet
 
      DispatcherServlet默认加载/WEB-INF/<servletName-servlet>.xml的Spring配置文件,启动WEB层的Spring容器。可以通过contextConfigLocation初始化参数自定义配置文件的位置和名称
 
  1. <!-- 配置 DispatcherServlet -->
  2. <servlet>
  3. <servlet-name>helloworld</servlet-name>
  4. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  5. <!-- 配置DispatcherServlet初始化参数:配置springmvc配置文件的位置和名称 -->
  6. <!--
  7. 实际上也可以不通过 contextConfigLocation 来配置 SpringMVC 的配置文件, 而使用默认的.
  8. 默认的配置文件为: /WEB-INF/<servlet-name>-servlet.xml
  9. 这样配置文件就不是放在src下了,而是放在WEB-INF下,此时名字叫做helloworld-servlet.xml
  10. -->
  11. <init-param>
  12. <param-name>contextConfigLocation</param-name>
  13. <param-value>classpath:springmvc.xml</param-value>
  14. </init-param>
  15. <load-on-startup>1</load-on-startup>
  16. </servlet>
  17. <servlet-mapping>
  18. <servlet-name>helloworld</servlet-name>
  19. <url-pattern>/</url-pattern>
  20. </servlet-mapping>
 

 ❤  创建Spring MVC配置文件

 
       –配置自动扫描的包
       –配置视图解析器:视图名称解析器:将视图逻辑名解析为: /WEB-INF/pages/<viewName>.jsp
 
  1. <!-- 配置自动扫描的包 -->
  2. <context:component-scan base-package="com.starfish.springmvc"></context:component-scan>
  3. <!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
  4. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  5. <property name="prefix" value="/WEB-INF/views/"></property>
  6. <property name="suffix" value=".jsp"></property>
  7. </bean>
 

 ❤  创建请求处理器类

 
 
  1. @Controller
  2. public class HelloWorld {
  3. /**
  4. * 1. 使用 @RequestMapping  注解来映射请求的 URL(这里的请求就是:href="helloWorld")
  5. * 2. 返回值会通过视图解析器解析为实际的物理视图, 对于 InternalResourceViewResolver 视图解析器, 会做如下的解析:
  6. * 通过 prefix + returnVal + 后缀 这样的方式得到实际的物理视图, 然会做转发操作
  7. *
  8. * /WEB-INF/views/success.jsp
  9. */
  10. @RequestMapping("/helloWorld")
  11. public String helloWorld(){
  12. System.out.println("springMVC HelloWorld!");
  13. return "success";
  14. }
  15. }
 
 
 
3.使用@RequestMapping映射请求
 

• spring MVC 使用@RequestMapping注解为控制器指定可以处理哪些URL 请求

• 在控制器的类定义及方法定义处都可标注@RequestMapping

– 类定义处:提供初步的请求映射信息。相对于WEB 应用的根目录

– 方法处:提供进一步的细分映射信息。相对于类定义处的URL。若类定义处未标注@RequestMapping,则方法处标记的URL 相对于WEB 应用的根目录

• DispatcherServlet截获请求后,就通过控制器上@RequestMapping提供的映射信息确定请求所对应的处理方法。

 
 ❤  使用@RequestMapping映射请求示例

        
 ❤  映射请求参数、请求方法或请求头
     • 标准的HTTP请求报头
         
 

• @RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法、请求参数及请求头映射请求

• @RequestMapping的value、method、params及heads 分别表示请求URL、请求方法、请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。

• paramsheaders支持简单的表达式:

– param1: 表示请求必须包含名为param1 的请求参数

– !param1: 表示请求不能包含名为param1 的请求参数

– param1 != value1: 表示请求包含名为param1 的请求参数,但其值不能为value1

– {“param1=value1”, “param2”}: 请求必须包含名为param1 和param2 的两个请求参数,且param1 参数的值必须为value1

 
  1. @Controller
  2. @RequestMapping("springmvc")
  3. public class SpringMVCTest {
  4. private static final String SUCCESS = "success";
  5. //了解:不常用, 可以使用params和header来更加精确的映射请求,他两支持简单的表达式
  6. @RequestMapping(value="testParamsAndHeader",params={"username","age!=24"},headers={"Accept-Language=zh-CN,zh;q=0.8"})
  7. public String testParamsAndHeader(){
  8. System.out.println("testParamsAndHeader...");
  9. return SUCCESS;
  10. }}
 
 

 ❤  @RequestMapping映射的url还可以使用通配符(需要使用Ant风格)

• Ant 风格资源地址支持3 种匹配符:

– ?:匹配文件名中的一个字符

– *:匹配文件名中的任意字符

– **:** 匹配多层路径

• @RequestMapping还支持Ant 风格的URL:

– /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

 
  1. @Controller
  2. @RequestMapping("springmvc")
  3. public class SpringMVCTest {
  4. private static final String SUCCESS = "success";
  5. @RequestMapping("/testAntPath/*/abc")
  6. public String testAntPath() {
  7. System.out.println("testAntPath");
  8. return SUCCESS;
  9. }    }
 

 ❤  @PathVariable映射URL 绑定的占位符

     • 带占位符的URL 是Spring3.0 新增的功能,该功能在SpringMVC向REST目标挺进发展过程中具有里程碑的意义
    • 通过@PathVariable可以将URL 中占位符参数绑定到控制器处理方法的参数中:URL 中的{xxx} 占位符可以通  过@PathVariable("xxx") 绑定到操作方法的入参中。
(占位符中的名字需要和@PathVariable中的名字一样)
 
  1. @Controller
  2. @RequestMapping("springmvc")
  3. public class SpringMVCTest {
  4. private static final String SUCCESS = "success";
  5. @RequestMapping("testPathVariable/{id}")
  6. public String testPathVariable(@PathVariable("id") Integer id){
  7. System.out.println("testPathVariable:" + id);
  8. return SUCCESS;
  9. }    }
  10. jsp:   <a:href="springmvc/testPathVariable/1">Test PathVariable</a>
 
 ❤  REST

• 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 用来删除资源。

• 示例

– /order/1  HTTP GET:得到id= 1 的order

– /order/1  HTTP DELETE:删除id = 1的order

–/order/1HTTP PUT:更新id = 1的order

–/order HTTP POST:新增order

     • HiddenHttpMethodFilter:浏览器form 表单只支持GET 与POST 请求,而DELETE、PUT 等method 并不支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的http 方法,使得支持GET、POST、PUT 与DELETE 请求。

 
  1. <!-- 在web.xml中配置 org.springframework.web.filter.HiddenHttpMethodFilter: 可以把 POST 请求转为 DELETE 或 PUT 请求    -->
  2. <filter>
  3. <filter-name>HiddenHttpMethodFilter</filter-name>
  4. <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  5. </filter>
  6. <filter-mapping>
  7. <filter-name>HiddenHttpMethodFilter</filter-name>
  8. <url-pattern>/*</url-pattern>
  9. </filter-mapping>
  10. ————————action——————————————————————————————————————————
  11. @Controller
  12. @RequestMapping("springmvc")
  13. public class SpringMVCTest {
  14. private static final String SUCCESS = "success";
  15. /**
  16. * Rest 风格的 URL.
  17. * 以 CRUD 为例:
  18. *     新增: /order POST
  19. * 修改: /order/1 PUT      update?id=1
  20. * 获取:     /order/1 GET     get?id=1
  21. * 删除: /order/1 DELETE   delete?id=1
  22. *
  23. * 如何发送 PUT 请求和 DELETE 请求呢 ?
  24. *  1. 需要配置 HiddenHttpMethodFilter
  25. *  2. 需要发送 POST 请求
  26. *  3. 需要在发送 POST 请求时携带一个 name="_method" 的隐藏域, 值为 DELETE 或 PUT
  27. *
  28. * 在 SpringMVC 的目标方法中如何得到 id 呢?
  29. * 使用 @PathVariable 注解
  30. *
  31. */
  32. @RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
  33. public String testRestPut(@PathVariable Integer id) {
  34. System.out.println("testRest Put: " + id);
  35. return SUCCESS;
  36. }
  37. @RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE)
  38. public String testRestDelete(@PathVariable Integer id) {
  39. System.out.println("testRest Delete: " + id);
  40. return SUCCESS;
  41. }
  42. @RequestMapping(value = "/testRest", method = RequestMethod.POST)
  43. public String testRest() {
  44. System.out.println("testRest POST");
  45. return SUCCESS;
  46. }
  47. @RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
  48. public String testRest(@PathVariable Integer id) {
  49. System.out.println("testRest GET: " + id);
  50. return SUCCESS;
  51. }    }
  52. ————————————————jsp————————————————————————————————————
  53. <form action="springmvc/testRest/1" method="post">
  54. <input type="hidden" name="_method" value="PUT"/>
  55. <input type="submit" value="TestRest PUT"/>
  56. </form>
  57. <br><br>
  58. <form action="springmvc/testRest/1" method="post">
  59. <input type="hidden" name="_method" value="DELETE"/>
  60. <input type="submit" value="TestRest DELETE"/>
  61. </form>
  62. <br><br>
  63. <form action="springmvc/testRest" method="post">
  64. <input type="submit" value="TestRest POST"/>
  65. </form>
  66. <br><br>
  67. <a href="springmvc/testRest/1">Test Rest Get</a>
  68. <br><br>
 

4. 映射请求参数&请求参数

 
 ❤  

请求处理方法签名

     • SpringMVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的相应人参中。
     • Spring MVC 对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。
     • 必要时可以对方法及方法入参标注相应的注解(@PathVariable、@RequestParam、@RequestHeader等)、Spring MVC 框架会将HTTP 请求的信息绑定到相应的方法入参中,并根据方法的返回值类型做出相应的后续处理。
 
 
  1. ————————————————jsp————————————————————————————————————
  2. <a href="springmvc/testRequestParam?userName=starfish&age=22">Test RequestParam</a>
  3. ————————————————action——————————————————————————————————
  4. @Controller
  5. @RequestMapping("springmvc")
  6. public class SpringMVCTest {
  7. private static final String SUCCESS = "success";
  8. @RequestMapping("/testRequestParam")
  9. public String testRequestParam(@RequestParam(value="userName") String userName,
  10. @RequestParam(value="age",required=false,defaultValue="18") int age){
  11. System.out.println("testRequestParam--> userName :"+ userName + ", age:"+ age);
  12. return SUCCESS;
  13. }
 
 
 
 ❤  使用@RequestParam绑定请求参数值
      • 在处理方法入参处使用@RequestParam可以把请求参数传递给请求方法
            – value:参数名
            – required:是否必须。默认为true, 表示请求参数中必须包含对应的参数,若不存在,将抛出异常
 
  1. @Controller
  2. @RequestMapping("springmvc")
  3. public class SpringMVCTest {
  4. private static final String SUCCESS = "success";
  5. @RequestMapping("/testRequestParam")
  6. public String testRequestParam(@RequestParam(value="userName") String userName,
  7. @RequestParam(value="age",required=false,defaultValue="18") int age){       //integer age可以不用写默认值
  8. System.out.println("testRequestParam--> userName :"+ userName + ", age:"+ age);
  9. return SUCCESS;
  10. }
  11. ——————————————————
  12. jsp:
  13. <a href="springmvc/testRequestParam?userName=starfish&age=22">Test RequestParam</a>
 
 
 ❤  使用@RequestHeader绑定请求报头的属性值
 
       • 请求头包含了若干个属性,服务器可据此获知客户端的信息,通过@RequestHeader即可将请求头中的属性值绑定到处理方法的入参中
 
  1. @Controller
  2. @RequestMapping("springmvc")
  3. public class SpringMVCTest {
  4. private static final String SUCCESS = "success";
  5. // 了解: 映射请求头信息 用法同 @RequestParam
  6. @RequestMapping("/testRequestHeader")
  7. public String testRequestHeader(
  8. @RequestHeader(value = "Accept-Language") String al) {
  9. System.out.println("testRequestHeader, Accept-Language: " + al);
  10. return SUCCESS;
  11. }
  12. ——————————————————
  13. jsp:
  14. <a href="springmvc/testRequestHeader">Test RequestHeader</a>
 
 

 ❤  使用@CookieValue绑定请求中的Cookie 值

 

• @CookieValue可让处理方法入参绑定某个Cookie 值

 
  1. @Controller
  2. @RequestMapping("springmvc")
  3. public class SpringMVCTest {
  4. private static final String SUCCESS = "success";
  5. //了解: @CookieValue: 映射一个 Cookie 值. 属性同 @RequestParam
  6. @RequestMapping("/testCookieValue")
  7. public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) {
  8. System.out.println("testCookieValue: sessionId: " + sessionId);
  9. return SUCCESS;
  10. }
  11. ——————————————————
  12. jsp:   <a href="springmvc/testCookieValue">Test CookieValue</a>
 
 

 ❤   使用POJO 对象绑定请求参数值(一般用的都是对象)

       • Spring MVC 会按请求参数名和POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。如:dept.deptId、dept.address.tel等
 
  1. ————————————POJO————————————————
  2. public class User {
  3. private String userName;
  4. private int age;
  5. private Address address;
  6. toString()方法和set,get方法省略。。}
  7. public class Address{
  8. private String province;
  9. private String city;
  10. toString()方法和set,get方法省略。。}
  11. ————————————action————————————————
  12. @Controller
  13. @RequestMapping("springmvc")
  14. public class SpringMVCTest {
  15. private static final String SUCCESS = "success";
  16. @RequestMapping("/testPOJO")
  17. public String testPOJO(User user){
  18. System.out.println(user);
  19. return SUCCESS;
  20. }}
  21. ——————————jsp——————————————————
  22. <form action="springmvc/testPOJO">
  23. username:<input type="text" name="userName"><br><br>
  24. age:<input type="text" name="age"><br><br>
  25. province:<input type="text" name="address.province"><br><br>
  26. city:<input type="text" name="address.city"><br><br>
  27. <input type="submit" value="Submit">
  28. </form>
 
 

 ❤  使用ServletAPI作为入参

     MVC 的Handler 方法可以接受哪些ServletAPI类型的参数:

• HttpServletRequest

• HttpServletResponse

• HttpSession

• Java.security.Principal•Locale

• InputStream

• OutputStream

• Reader

• Writer

 
  1. ————————————action————————————————
  2. @Controller
  3. @RequestMapping("/testServletAPI")
  4. public void testServletAPI(HttpServletRequest request,
  5. HttpServletResponse response, Writer out) throws IOException {
  6. System.out.println("testServletAPI, " + request + ", " + response);
  7. out.write("hello springmvc");
  8. //        return SUCCESS;
  9. }
  10. }
  11. ——————————jsp——————————————————
  12. <a href="springmvc/testServletAPI">Test ServletAPI</a>
 

5.处理模型数据

 ❤ Spring MVC 提供了以下几种途径输出模型数据

– ModelAndView: 处理方法返回值类型为ModelAndView时, 方法体即可通过该对象添加模型数据

– Map 及Model: 入参为org.springframework.ui.Model、org.springframework.ui.ModelMap或java.uti.Map时,处理方法返回时,Map 中的数据会自动添加到模型中。

– @SessionAttributes: 将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性

– @ModelAttribute: 方法入参标注该注解后, 入参的对象就会放到数据模型中

 
 ❤ ModelAndView

• 控制器处理方法的返回值如果为ModelAndView, 则其既包含视图信息,也包含模型数据信息。

• 添加模型数据:

– MoelAndView addObject(String attributeName, Object attributeValue)

– ModelAndView addAllObject(Map<String, ?> modelMap)

• 设置视图:

– void setView(View view)

– void setViewName(String viewName)j

 
  1. ————————————action————————————————
  2. /**
  3. * 目标方法的返回值可以是 ModelAndView 类型。
  4. * 其中可以包含视图和模型信息
  5. * SpringMVC 会把 ModelAndView 的 model 中数据放入到 request 域对象中.
  6. * @return
  7. */
  8. @RequestMapping("/testModelAndView")
  9. public ModelAndView testModelAndView(){
  10. String viewName = SUCCESS;
  11. ModelAndView modelAndView = new ModelAndView(viewName);
  12. //添加模型数据到 ModelAndView 中.
  13. modelAndView.addObject("time", new Date());
  14. return modelAndView;
  15. }
  16. ——————————jsp——————————————————
  17. <a href="springmvc/testModelAndView">Test ModelAndView</a>
  18. success page:     time: ${requestScope.time }
 
 ❤ Map及Model
     •  Spring MVC 在内部使用了一个org.springframework.ui.Model接口存储模型数据
     •  具体步骤:
        – Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
        – 如果方法的入参为Map 或Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据
 
 
  1. ————————————action————————————————
  2. /**
  3. * 目标方法可以添加 Map 类型(实际上也可以是 Model 类型或 ModelMap 类型)的参数.
  4. * @param map
  5. * @return
  6. */
  7. @RequestMapping("/testMap")
  8. public String testMap(Map<String, Object> map){
  9. System.out.println(map.getClass().getName());
  10. map.put("names", Arrays.asList("Tom", "Jerry", "Mike"));
  11. return SUCCESS;
  12. }
  13. ——————————jsp——————————————————
  14. <a href="springmvc/testMap">Test testMap
  15. </a>                       success page:
  16. names: ${requestScope.name }


 ❤ @SessionAttributes
前边几种方法都是把模型数据放到域对象中,也可以放在session中
 
     • 若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个@SessionAttributes, Spring MVC 将在模型中对应的属性暂存到HttpSession中。
     • @SessionAttributes除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
         – @SessionAttributes(types=User.class) 会将隐含模型中所有类型为User.class的属性添加到会话中。
         – @SessionAttributes(value={“user1”, “user2”})
         – @SessionAttributes(types={User.class, Dept.class})
         – @SessionAttributes(value={“user1”, “user2”}, types={Dept.class})
 
  1. ————————————action————————————————
  2. @Controller
  3. @RequestMapping("springmvc")
  4. @SessionAttributes(value={"user"},types={String.class})         //将user也放在了session域里边,只要是String类型的值,也会放在session中
  5. public class SpringMVCTest {
  6. /**
  7. * @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(实际上使用的是 value 属性值),
  8. * 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用的是 types 属性值)
  9. * 注意: 该注解只能放在类的上面. 而不能修饰放方法.
  10. */
  11. @RequestMapping("/testSessionAttributes")
  12. public String testSessionAttributes(Map<String,Object> map){
  13. User user = new User("starfish", 24);
  14. map.put("school", "naoyao");
  15. map.put("user", user);
  16. return SUCCESS;
  17. }    }
  18. ——————————jsp——————————————————
  19. <a href="springmvc/testSessionAttributes">Test SessionAttributes</a>
  20. success page:
  21. request user: ${requestScope.user }
  22. <br><br>
  23. session user: ${sessionScope.user }
  24. <br><br>
  25. request school: ${requestScope.school }
  26. <br><br>
  27. session school: ${sessionScope.school }
 
 
 ❤ 

@ModelAttribute
           
在方法定义上使用@ModelAttribute注解:
      • Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute的方法。
在方法的入参前使用@ModelAttribute注解:
         – 可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数绑定到对象中,再传入入参
        – 将方法入参对象添加到模型中
 
  1. ————————————action————————————————
  2. @Controller
  3. @RequestMapping("springmvc")
  4. public class SpringMVCTest {
  5. /**
  6. * 1. 有 @ModelAttribute 标记的方法, 会在每个目标方法执行之前被 SpringMVC 调用!
  7. * 2. @ModelAttribute 注解也可以来修饰目标方法 POJO 类型的入参, 其 value 属性值有如下的作用:
  8. * 1). SpringMVC 会使用 value 属性值在 implicitModel 中查找对应的对象, 若存在则会直接传入到目标方法的入参中.
  9. * 2). SpringMVC 会以 value 为 key, POJO 类型的对象为 value, 存入到 request 中.
  10. */
  11. @ModelAttribute
  12. public void getUser(@RequestParam(value="id",required=false) Integer id,
  13. Map<String, Object> map){
  14. System.out.println("modelAttribute method");
  15. if(id != null){
  16. //模拟从数据库中获取对象
  17. User user = new User(1, "Tom", "123456", "tom@atguigu.com", 12);
  18. System.out.println("从数据库中获取一个对象: " + user);
  19. map.put("user", user);
  20. }  }
  21. /**
  22. * 运行流程:
  23. * 1. 执行 @ModelAttribute 注解修饰的方法: 从数据库中取出对象, 把对象放入到了 Map 中. 键为: user
  24. * 2. SpringMVC 从 Map 中取出 User 对象, 并把表单的请求参数赋给该 User 对象的对应属性.
  25. * 3. SpringMVC 把上述对象传入目标方法的参数.
  26. *
  27. * 注意: 在 @ModelAttribute 修饰的方法中, 放入到 Map 时的键需要和目标方法入参类型的第一个字母小写的字符串一致!
  28. *         map.put("user", user);   必须是"user"
  29. *
  30. * SpringMVC 确定目标方法 POJO 类型入参的过程
  31. * 1. 确定一个 key:
  32. * 1). 若目标方法的 POJO 类型的参数木有使用 @ModelAttribute 作为修饰, 则 key 为 POJO 类名第一个字母的小写
  33. * 2). 若使用了  @ModelAttribute 来修饰, 则 key 为 @ModelAttribute 注解的 value 属性值.
  34. * 2. 在 implicitModel 中查找 key 对应的对象, 若存在, 则作为入参传入
  35. * 1). 若在 @ModelAttribute 标记的方法中在 Map 中保存过, 且 key 和 1 确定的 key 一致, 则会获取到.
  36. * 3. 若 implicitModel 中不存在 key 对应的对象, 则检查当前的 Handler 是否使用 @SessionAttributes 注解修饰,
  37. * 若使用了该注解, 且 @SessionAttributes 注解的 value 属性值中包含了 key, 则会从 HttpSession 中来获取 key 所
  38. * 对应的 value 值, 若存在则直接传入到目标方法的入参中. 若不存在则将抛出异常.
  39. * 4. 若 Handler 没有标识 @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key, 则
  40. * 会通过反射来创建 POJO 类型的参数, 传入为目标方法的参数
  41. * 5. SpringMVC 会把 key 和 POJO 类型的对象保存到 implicitModel 中, 进而会保存到 request 中.
  42. *
  43. * 源代码分析的流程
  44. * 1. 调用 @ModelAttribute 注解修饰的方法. 实际上把 @ModelAttribute 方法中 Map 中的数据放在了 implicitModel 中.
  45. * 2. 解析请求处理器的目标参数, 实际上该目标参数来自于 WebDataBinder 对象的 target 属性
  46. * 1). 创建 WebDataBinder 对象:
  47. * ①. 确定 objectName 属性: 若传入的 attrName 属性值为 "", 则 objectName 为类名第一个字母小写.
  48. * *注意: attrName. 若目标方法的 POJO 属性使用了 @ModelAttribute 来修饰, 则 attrName 值即为 @ModelAttribute
  49. * 的 value 属性值
  50. *
  51. * ②. 确定 target 属性:
  52. *     > 在 implicitModel 中查找 attrName 对应的属性值. 若存在, ok
  53. *     > *若不存在: 则验证当前 Handler 是否使用了 @SessionAttributes 进行修饰, 若使用了, 则尝试从 Session 中
  54. * 获取 attrName 所对应的属性值. 若 session 中没有对应的属性值, 则抛出了异常.
  55. *     > 若 Handler 没有使用 @SessionAttributes 进行修饰, 或 @SessionAttributes 中没有使用 value 值指定的 key
  56. * 和 attrName 相匹配, 则通过反射创建了 POJO 对象
  57. *
  58. * 2). SpringMVC 把表单的请求参数赋给了 WebDataBinder 的 target 对应的属性.
  59. * 3). *SpringMVC 会把 WebDataBinder 的 attrName 和 target 给到 implicitModel.
  60. * 近而传到 request 域对象中.
  61. * 4). 把 WebDataBinder 的 target 作为参数传递给目标方法的入参.
  62. */
  63. @RequestMapping("/testModelAttribute")
  64. public String testModelAttribute(User user){
  65. System.out.println("修改: " + user);
  66. return SUCCESS;
  67. }}
  68. ——————————————jsp————————————————————
  69. <!--
  70. 模拟修改操作
  71. 1. 原始数据为: 1, Tom, 123456,tom@atguigu.com,12
  72. 2. 密码不能被修改.
  73. 3. 表单回显, 模拟操作直接在表单填写对应的属性值
  74. -->
  75. <form action="springmvc/testModelAttribute" method="Post">
  76. <input type="hidden" name="id" value="1"/>
  77. username: <input type="text" name="username" value="Tom"/>
  78. <br>
  79. email: <input type="text" name="email" value="tom@atguigu.com"/>
  80. <br>
  81. age: <input type="text" name="age" value="12"/>
  82. <br>
  83. <input type="submit" value="Submit"/>
  84. </form>
  85. <br><br>
 
 
  ❤ 由@SessionAttributes引发的异常

     • 如果在处理类定义处标注了@SessionAttributes(“xxx”),则尝试从会话中获取该属性,并将其赋给该入参,然后再用请求消息填充该入参对象。如果在会话中找不到对应的属性,则抛出HttpSessionRequiredException异常
 
 

如何避免@SessionAttributes引发的异常

(必须加上如下带有@ModelAttribute的方法)

 
 
1

0

Spring MVC 学习笔记(一)的更多相关文章

  1. Spring MVC 学习笔记一 HelloWorld

    Spring MVC 学习笔记一 HelloWorld Spring MVC 的使用可以按照以下步骤进行(使用Eclipse): 加入JAR包 在web.xml中配置DispatcherServlet ...

  2. Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建

    Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...

  3. Spring MVC 学习笔记11 —— 后端返回json格式数据

    Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...

  4. Spring MVC 学习笔记10 —— 实现简单的用户管理(4.3)用户登录显示全局异常信息

    </pre>Spring MVC 学习笔记10 -- 实现简单的用户管理(4.3)用户登录--显示全局异常信息<p></p><p></p>& ...

  5. Spring MVC 学习笔记9 —— 实现简单的用户管理(4)用户登录显示局部异常信息

    Spring MVC 学习笔记9 -- 实现简单的用户管理(4.2)用户登录--显示局部异常信息 第二部分:显示局部异常信息,而不是500错误页 1. 写一个方法,把UserException传进来. ...

  6. Spring MVC 学习笔记8 —— 实现简单的用户管理(4)用户登录

    Spring MVC 学习笔记8 -- 实现简单的用户管理(4)用户登录 增删改查,login 1. login.jsp,写在外面,及跟WEB-INF同一级目录,如:ls Webcontent; &g ...

  7. Spring MVC 学习笔记2 - 利用Spring Tool Suite创建一个web 项目

    Spring MVC 学习笔记2 - 利用Spring Tool Suite创建一个web 项目 Spring Tool Suite 是一个带有全套的Spring相关支持功能的Eclipse插件包. ...

  8. Spring MVC 学习笔记1 - First Helloworld by Eclipse【& - java web 开发Tips集锦】

    Spring MVC 学习笔记1 - First Helloworld by Eclipse reference:http://www.gontu.org 1. 下载 Spring freamwork ...

  9. Spring MVC 学习笔记(整理)

    SpringMVC学习 1.概述 Spring MVC是一种基于Java实现MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行解耦,基于请求-响应模型帮助我们 ...

  10. spring MVC学习笔记

    为开发团队选择一款优秀的MVC框架是件难事儿,在众多可行的方案中决择需要很高的经验和水平.你的一个决定会影响团队未来的几年.要考虑方面太多: 1.简单易用,以提高开发效率.使小部分的精力在框架上,大部 ...

随机推荐

  1. vmware linux 硬盘空间不足时增加硬盘并挂载

    不同的版本的vmware在设置界面中可能稍有不同,基本是一致的. 还有一种方式是扩展,这里没有记录,扩展时需要在虚拟机关机状态下. 1.选择在vmware中点击设置并打开,将光标定位在hard Dis ...

  2. MaskRCNN 奔跑自己的数据

    import os import sys import random import math import re import time import numpy as np import cv2 i ...

  3. LeetCode 643. 子数组最大平均数 I(Maximum Average Subarray I)

    643. 子数组最大平均数 I 643. Maximum Average Subarray I 题目描述 给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. LeetCo ...

  4. NumPy使用图解教程

    NumPy是Python中用于数据分析.机器学习.科学计算的重要软件包.它极大地简化了向量和矩阵的操作及处理.python的不少数据处理软件包依赖于NumPy作为其基础架构的核心部分(例如scikit ...

  5. phaser三个学生做题目

    3个学生一起参加考试,一共有三道题,要求所有学生到齐才能开始考试,全部同学都做完第一题,学生才能继续做第二题,全部学生做完了第二题,才能做第三题,所有学生都做完的第三题,考试才结束 public cl ...

  6. 剑指offer66:机器人的运动范围

    1 题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时,机器 ...

  7. Windows Subsystem for Linux(wsl)使用

    由于项目有一些环境需要在linux环境运行.可用微软win10的WSL来搭配使用 安装wsl 控制面板--程序和功能--启用或关闭windows功能,适用于linux的windows系统 应用商城下载 ...

  8. 利用Python进行数据分析 第8章 数据规整:聚合、合并和重塑.md

    学习时间:2019/11/03 周日晚上23点半开始,计划1110学完 学习目标:Page218-249,共32页:目标6天学完(按每页20min.每天1小时/每天3页,需10天) 实际反馈:实际XX ...

  9. c#使用GDI进行简单的绘图

    https://www.2cto.com/database/201805/749421.html https://zhidao.baidu.com/question/107832895.html pr ...

  10. mysql建表常用命令

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RD ...