Spring MVC学习随笔-控制器(Controller)开发详解:控制器跳转与作用域(二 ...

打印 上一主题 下一主题

主题 917|帖子 917|积分 2751

学习视频:孙哥说SpringMVC:结合Thymeleaf,重塑你的MVC世界!|前所未有的Web开发探索之旅
衔接上文Spring MVC学习随笔-控制器(Controller)开发详解:控制器跳转与作用域(一)

  • SpingMVC中request作用域的处理

    • 代码
      1. # 基于Model的方式
      2. @RequestMapping("view2")
      3. public String view2(Model model) {
      4.                 // 等同于 request.addAttribute();
      5.     model.addAttribute("name", "suns");
      6.     return "result1";
      7. }
      8. # 基于ModelMap的方式 同上
      9. @RequestMapping("view3")
      10. public String view3(ModelMap modelMap) {
      11.     modelMap.addAttribute("name", "suns2");
      12.     return "result1";
      13. }
      复制代码
    • Model、ModelMap相关细节分析

      • 通过Model、ModelMap进行作用域处理,可以解决视图模板技术耦合的问题
        因为SpringMVC通过视图解析器区别JSP、FreeMaker,再将Model、ModelMap的数据放到request或root里面运行。

      • SpringMVC中提供Model和ModelMap两种方式处理request作用域,他们的区别是什么
        虽然两者表现形式以及声明的形参类型都不同,但是在运行时,SpringMVC会动态提供对应的实现类型,名字是BindingAwareModelMap。所以本质上两者相同。
      • 为什么不直接使用BindingAwareModelMap?
        在源码中,Model接口会根据开发者使用SpringMVC或Spring WebFlux进行自动适配,使用MVC开发时会使用BindingAwareModelMap,而WebFlux开发时使用的是ConcurrentModel。


      • SpringMVC为什么会提供两种开发方式?Model、ModelMap这两种开发方式,更推荐哪种使用?
        推荐使用Model,ModelMap是老系统使用的,为了兼容老系统所以留着。Model可以兼容传统MVC也可以在WebFlux中使用,更有利于项目维护。
      • 如果redirect跳转,数据如何跳转
        SpringMVC会自动把Model或ModelMap中的数据,通过?的形式在url上进行拼接,从而传递数据


  • SpringMVC中Session作用域的处理

    • 基本使用方式及其存在的问题
      1. session.setAttribute("name","value");
      2. @RequestMapping("view")
      3. public String view1(HttpSession session){
      4.                 session.setAttribute("name","value");
      5.                 return "result";
      6. }
      7. 存在问题:与ServletAPI耦合,在SpringMVC中不建议使用。
      复制代码
    • @SessionAttributes注解

      • 存储数据
        1. @Controller
        2. @RequestMapping("view3")
        3. **@SessionAttributes(value = "name")  // 声明name存在session作用域**
        4. public class View3Controller {
        5.     @RequestMapping("view1")
        6.     public String view1(Model model) {
        7.         model.addAttribute("name", "xiaojr");
        8.                                 model.addAttribute("age", 10);
        9.         return "result1";
        10.     }
        11. }
        12. // jsp中取值
        13. <html>
        14. <body>
        15.     <h1>session attribute is ${sessionScope.name}</h1>
        16.     <h1>request attribute is ${requestScope.age}</h1>
        17. </body>
        18. </html>
        复制代码
      • 注意

        • Model、ModelMap把name的数据通过@SessionAttributes存储在Session作用域中的同时在Request作用域中也会存储。
        • 此时Request作用域、Session作用域存储的是一个对象的引用。


    • 删除Session作用域中的数据


  • SpringMVC中application作用域的处理

  • 为什么SpringMVC没有提供application作用域
    因为application这个作用域是全局唯一,在开发中多用于存储全局唯一的对象,被框架底层封装,在开发时,程序员基本不会使用其用于业务操作。
  • @ModelAttribute注解

    • SpringMVC通过@ModelAttribute注解:接受请求参数的同时,把数据存储到request作用域中。
      1. @RequestMapping("view1")
      2. public String view1(@ModelAttribute("name") String name) {
      3.     System.out.println("View4Controller.view1");
      4.     return "result2";
      5. }
      复制代码


    • 使用场景

      传递页码时可以使用。
    • 注意细节

      • 细节一
        如果传递的是简单变量参数:则value属性必须与超级链接或表单的key名称保持一致。
        如果传递的是POJO类型的请求参数:则没有上述要求,但是value属性会作为request作用域的名称。
      • 细节二

        • @ModelAttribute中value的值不能与@SessionAttributes中value的值一致,如果一致则会产生异常
        • 如果要把请求参数的数据也存在session作用域中,需要将request作用域存储改为使用传统做法:model.addAttribute(”name”,name);



  • 什么是ModelAndView【了解】

    • 什么是ModelAndView
      ModelAndView这个类型,实际上是一个复合类型,起到了2个方面的作用。
      注意:ModelAndView里面只能使用ModelMap,这也是它的劣势之一。

      • Model 代表作用域的操作,就是前面的ModelMap。
      • View 代表跳转路径(页面),对应前面的四种跳转。
      最终这两方面的工作统一被ModelAndView进行封装,做为控制器方法的返回值使用。


    • 总结目前控制器方法返回值
      1. 1. public String controller();
      2. 2. public ModelAndView controller();
      3. 注意:SpringMVC处理跳转页面和作用域时,把相应的内容都会封装到ModelAndView中,
      4. 所以ModelAndView返回值的这种处理更加底层,而返回值String的处理仅是简化开发。
      复制代码

5.5 视图控制器

5.5.1 什么是视图控制器


  • 视图控制器可以通过配置的方式,访问受保护的视图模板,简化开发。
  • 什么是视图模板?
    JSP Thymeleaf FreeMarker  Velocity
  • 为什么需要保护视图模板?
    目前的开发方式都没有对视图模板进行保护,有可能导致程序在被用户访问时产生非预期效果(Bug)
  • 如何保护视图模板
    将所有视图模板放置在WEB-INF下,这样用户就无法通过地址直接访问视图模板了。

5.5.1 受保护的视图模板如何访问?


  • 所有的视图模板,只能通过控制器forward访问:return "result"; return "forward:/WEB-INF/jsp/result.jsp";
    记得同时修改viewResolver
    1. <bean id="viewResolver" >
    2.     <property name="prefix" **value="/WEB-INF/jsp/"/>**
    3.     <property name="suffix" value=".jsp"/>
    4. </bean>
    复制代码
5.5.2 视图控制器

虽然可以通过控制器forward访问视图模板,但是直接访问页面也需要控制器,因此会变得繁琐,所以有了视图控制器的存在:通过在配置文件(dispatcher.xml)可以直接访问
  1. <mvc:view-controller path="/result3" view-name="result3"/>
  2. 注意:path不能和@RequestMapping的路径冲突
复制代码

5.5.3 视图控制器的Redirect跳转
  1. @RequestMapping("view1")
  2. public String view1() {
  3.     System.out.println("View6Controller.view1");
  4.     return "redirect:/result4";
  5. }
  6. <mvc:view-controller path="/result4" view-name="result4"/>
复制代码
5.6 静态资源处理

5.5.1 什么是静态资源


  • 所谓静态资源,指的是项目中非java代码部分的内容,如 图片、js文件、css文件。


  • 目前SpringMVC的开发中,按照现有的配置内容,是无法访问静态资源的。

g)
在SpringMVC底层,资源请求访问DispatcherServlet后,会将其请求当成控制器并调用对应的控制器方法创建对象,但是在静态资源访问,第一步就走不通了,所以就报错404。
5.5.3 解决方式


  • 方式一【DefaultServlet】
    Tomcat提供了能够访问静态资源的DefaultServlet(web.xml)

    在web.xml添加DefaultServlet后的代码:

  • 方式二【default-servlet-handler】推荐

    • 第一种开发方式的问题


  • default-servlet-handler开发方式

    • 在SpringMVC的配置文件(dispatcher.xml)中,配置即可

  • 实现原理

    • 标签的底层也是调用了defaultServlet进行的静态资源处理。
    • 标签他是如何调用defaultServlet进行静态资源处理的?
      他的底层是通过DefaultServletHttpRequestHandler,以forward的形式调用的DefaultServlet。

    mvc:default-servlet-handler/完整运行流程:用户如果发起控制器的请求,首先会到DispatcherServlet,然后DispatcherServlet会通过RequestMappingHandlerMapiping查找控制器上@RequestMapping注解并进行相应的匹配,进而查找,如果查找到则会通过HandlerAdapter进行处理。对于静态资源的操作,也就是使用了的处理,它的请求也一样会访问DispatcherServlet,没查找到则会通过SimpleUrlHandlerMapping调用DefaultServletHttpRequestHandler进而调用DefaultServlet进行静态资源的处理。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表