SpringMVC学习总结 + 【手写SpringMVC底层机制焦点】

打印 上一主题 下一主题

主题 908|帖子 908|积分 2724

SpringMVC笔记

SpringMVC介绍

基本介绍


  • SpringMVC 是WEB 层框架, 接受了Web 层组件, 支持MVC 的开发模式/开发架构
  • SpringMVC 通过注解,让POJO 成为控制器,不需要继承类或者实现接口
  • SpringMVC 接纳低耦合的组件设计方式,具有更好扩展和灵活性.
  • 支持REST 格式的URL 请求.
Spring MVC和Spring之间的关系


  • Spring MVC 只是Spring 处置处罚WEB 层请求的一个模块/组件, Spring MVC 的基石是Servlet  【Java WEB】
  • Spring Boot 是为了简化开发者的使用, 推出的封神框架(约定优于配置,简化了Spring的配置流程), SpringBoot 包罗许多组件/框架,Spring 就是最焦点的内容之一,也包罗SpringMVC
  • Spring Boot > Spring > Spring MVC
@RequestMapping

基本介绍

@RequestMapping 注解可以指定控制器/处置处罚器的某个方法的请求的url
  1. @RequestMapping(value = "/buy")
  2.     public String buy(){
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>System.out.println("购买商品");
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>return "success";
  13.     }
复制代码
其它使用方式


  • @RequestMapping 可以修饰方法和类

    • @RequestMapping 注解可以修饰方法,还可以修饰类当同时修饰类和方法时,
      请求的url 就是组合/类请求值/方法请求值
    1. @RequestMapping(value = "/user" )@Controller public class UserHandler {<?xml version="1.0" encoding="UTF-8" ?>
    2. <beans>
    3.    
    4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    5. </beans>@RequestMapping(value = "/buy")
    6.     public String buy(){
    7. <?xml version="1.0" encoding="UTF-8" ?>
    8. <beans>
    9.    
    10.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    11. </beans>System.out.println("购买商品");
    12. <?xml version="1.0" encoding="UTF-8" ?>
    13. <beans>
    14.    
    15.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    16. </beans>return "success";
    17.     }}
    复制代码
    此时url = /user/buy

  • @RequestMapping 可以指定请求方式

    • @RequestMapping 还可以指定请求的方式(post/get/put/delete..), 请求的方式需
      要和指定的一样,否则报错

  1. @RequestMapping(value = "/find", method = RequestMethod.GET)
  2.     public String search(String bookId) {
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>System.out.println("查询书籍bookId= " + bookId);
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>return "success";
  13.     }
复制代码

  • SpringMVC 控制器默认支持GET 和POST 两种方式, 也就是你不指定method , 可以接收
    GET 和POST 请求
  1. @RequestMapping(value = "/buy")//默认支持GET 和POST 两种方式
  2.     public String buy(){
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>System.out.println("购买商品");
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>return "success";
  13.     }
复制代码
3.@RequestMapping 可指定params 和headers 支持简单表达式

  • param1: 表示请求必须包罗名为param1 的请求参数
  • !=param1: 表示请求不能包罗名为param1 的请求参数
  • param1 != value1: 表示请求包罗名为param1 的请求参数,但其值不能为value1
  • {"param1=value1", "param2"}: 请求必须包罗名为param1 和param2 的两个请求参数,
    且param1 参数的值必须为value1
  1. @RequestMapping(value = "/find", params = "bookId", method = RequestMethod.GET)
  2. public String search(String bookId) {
  3. System.out.println("查询书籍bookId= " + bookId);
  4. return "success";
  5. }
复制代码
4.@RequestMapping 支持Ant 风格资源地址

  • ?:匹配文件名中的一个字符
  • *:匹配文件名中的恣意字符
  • **:匹配多层路径

    • Ant 风格的url 地址举例
      /user/*/createUser: <bean >
              <property name="order" value="99"></property>
      </bean><bean >
              <property name="order" value="99"></property>
      </bean>  匹配/user/aaa/createUser、/user/bbb/createUser 等URL
      /user/**/createUser: <bean >
              <property name="order" value="99"></property>
      </bean><bean >
              <property name="order" value="99"></property>
      </bean>匹配/user/createUser、/user/aaa/bbb/createUser 等URL
      /user/createUser??: <bean >
              <property name="order" value="99"></property>
      </bean><bean >
              <property name="order" value="99"></property>
      </bean>   匹配/user/createUseraa、/user/createUserbb 等URL

5.@RequestMapping 可配合@PathVariable 映射URL 绑定的占位符

  • 不需要在url 地址上带参数名了,更加的简洁明了
  1. // 我们希望目标方法获取到username 和userid, value="/xx/{username}" -@PathVariable("username")
  2.     @RequestMapping(value = "/reg/{username}/{userId}")
  3.     public String register(@PathVariable("username") String username,
  4.     <bean id="messageSource" class=
  5. <mvc:interceptor>
  6.     <mvc:mapping path="/h*"/>
  7.     <mvc:exclude-mapping path="/hello"/>
  8.     <ref bean="myInterceptor02"/>
  9. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  10. <?xml version="1.0" encoding="UTF-8" ?>
  11. <beans>
  12.    
  13.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  14. </beans>
  15. <?xml version="1.0" encoding="UTF-8" ?>
  16. <beans>
  17.    
  18.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  19. </beans><property name="basename" value="i18n"></property>
  20.     </bean>    @PathVariable("userId") String userId){
  21. <?xml version="1.0" encoding="UTF-8" ?>
  22. <beans>
  23.    
  24.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  25. </beans>System.out.println("接收到参数--" + "username= " + username + "--" + "usreid= " + userId);
  26. <?xml version="1.0" encoding="UTF-8" ?>
  27. <beans>
  28.    
  29.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  30. </beans>return "success";
  31.     }
复制代码
  1. <a target="_blank" href="https://www.cnblogs.com/user/reg/kristina/300">占位符的演示</a>
复制代码
6.请求的简写情势
​<bean >
        <property name="order" value="99"></property>
</bean><bean >
        <property name="order" value="99"></property>
</bean>@GetMapping @PostMapping @PutMapping @DeleteMapping
Rest请求风格

基本介绍


  • REST:即Representational State Transfer。(资源)表现层状态转化。是现在流行的请求方式。它结构清楚, 许多网站接纳。
  • HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:
  • GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
传统的请求方法

在url中:
getBook?id=1 GET
delete?id=1 GET
update POST
add POST
分析: 传统的url 是通过参数来分析crud 的类型,rest 是通过get/post/put/delete 来分析crud 的类型
REST 的焦点过滤器


  • 当前的浏览器只支持post/get 请求,因此为了得到put/delete 的请求方式需要使用Spring
    提供的HiddenHttpMethodFilter 过滤器进行转换.
  • HiddenHttpMethodFilter:浏览器form 表单只支持GET 与POST 请求,而DELETE、PUT
    等method 并不支持,Spring 添加了一个过滤器,可以将这些请求转换为标准的http 方
    法,使得支持GET、POST、PUT 与DELETE 请求
  • HiddenHttpMethodFilter 能对post 请求方式进行转换
  • 过滤器需要在web.xml 中配置
配置过滤器
  1. <filter>
  2.     <filter-name>hiddenHttpMethodFilter</filter-name>
  3.     <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6.     <filter-name>hiddenHttpMethodFilter</filter-name>
  7.     <url-pattern>/*</url-pattern>
  8. </filter-mapping>
复制代码
当我们需要 用delete/put 的方式时,
name="_method" 名字需要写成_method 因为背景的HiddenHttpMethodFilter
就是按这个名字来获取hidden 域的值,从而进行请求转换的.
  1. [/code][code]public String delBook(@PathVariable("id") String id) {
  2. System.out.println("删除书籍id= " + id);
  3. //return "success"; [如果这样返回会报错JSPs only permit GET POST orHEAD]
  4. return "redirect:/user/success"; //重定向到一个没有指定method 的Handler 方法
  5. }
复制代码
注意事项


  • HiddenHttpMethodFilter, 在将post 转成delete / put 请求时,是按_method 参数名来读取的
  • 如果web 项目是运行在Tomcat 8 及以上,会发现被过滤成DELETE 和PUT 请求,到达控制器时能顺利实行,但是返回时(forward)会报HTTP 405 的错误提示:消息JSP 只允许GET、POST 或HEAD。
  • 因此,将请求转发(forward)改为请求重定向(redirect):重定向到一个Handler,由Handler 转发到页面
SpringMVC映射请求数据

获取参数值
  1. /**
  2. * @RequestParam(value="name", required=false)
  3. * 1.@RequestParam : 表示说明一个接受到的参数
  4. * 2.value="name" : 接收的参数名是name
  5. * 3.required=false : 表示该参数可以有,也可以没有,如果required=true,表示必须传递该参数.
  6. * 默认是required=true
  7. */
  8. @RequestMapping("vote01")
  9.     public String test01(@RequestParam(value = "name",required = false) String username){
  10. <?xml version="1.0" encoding="UTF-8" ?>
  11. <beans>
  12.    
  13.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  14. </beans>System.out.println("得到的username= "+username);
  15. <?xml version="1.0" encoding="UTF-8" ?>
  16. <beans>
  17.    
  18.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  19. </beans>return "success";
  20.     }
复制代码

  • @RequestParam 表示会接收提交的参数
  • value = "name" 表示提交的参数名是name
  • required = false 表示该参数可以没有,默认是true 表示必须有这个参数
  • 当我们使用@RequestParam(value = "name",required = false) 就表示 请求的参数名和目的方法的形参名 可以不一致
获取Http请求消息头
  1. @RequestMapping(value = "/vote02")
  2.     public String test02(@RequestHeader(value = "Accept-Encoding")String ae,
  3.     <bean id="messageSource" class=
  4. <mvc:interceptor>
  5.     <mvc:mapping path="/h*"/>
  6.     <mvc:exclude-mapping path="/hello"/>
  7.     <ref bean="myInterceptor02"/>
  8. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  9. <?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>
  14. <?xml version="1.0" encoding="UTF-8" ?>
  15. <beans>
  16.    
  17.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  18. </beans><property name="basename" value="i18n"></property>
  19.     </bean>@RequestHeader(value = "Host")String host) {
  20. <?xml version="1.0" encoding="UTF-8" ?>
  21. <beans>
  22.    
  23.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  24. </beans>System.out.println("Accept-Encoding =" + ae);
  25. <?xml version="1.0" encoding="UTF-8" ?>
  26. <beans>
  27.    
  28.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  29. </beans>System.out.println("Host =" + host);
  30. <?xml version="1.0" encoding="UTF-8" ?>
  31. <beans>
  32.    
  33.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  34. </beans>//返回到一个结果
  35. <?xml version="1.0" encoding="UTF-8" ?>
  36. <beans>
  37.    
  38.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  39. </beans>return "success";
  40.     }
复制代码
获取javabean 情势的数据
  1. @RequestMapping(value = "/vote03")
  2.     public String test03(Master master) {
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>System.out.println("主人信息= " + master);
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>//返回结果
  13. <?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>return "success";
  18.     }
复制代码

  • 方法的形参 (Master master) 用对应的对象类型指定即可,SpringMVC会自动的进行封装
  • 如果自动的完成封装,要求提交的数据参数名和对象的字段名保持一致
  • 支持级联数据获取: 如果对象的属性任然是一个对象,就通过    字段名.字段名 来提交
    比如Master[Pet]<bean >
            <property name="order" value="99"></property>
    </bean>,可以通过<bean >
            <property name="order" value="99"></property>
    </bean> pet.id ,pet.name<bean >
            <property name="order" value="99"></property>
    </bean>来指定
  • 如果参数名和字段名不匹配,则对象的属性就是null
ServletAPI


  • 开发中原生的ServletAPI仍然可以使用
  1. @RequestMapping(value = "/vote04")
  2.     public String test04(HttpServletRequest request,HttpServletResponse response) {
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>String username = request.getParameter("username");
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>String password = request.getParameter("password");
  13. <?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>System.out.println("username= "+username+" ,password= "+password);
  18. <bean >
  19.         <property name="order" value="99"></property>
  20. </bean><bean >
  21.         <property name="order" value="99"></property>
  22. </bean>//返回结果
  23. <?xml version="1.0" encoding="UTF-8" ?>
  24. <beans>
  25.    
  26.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  27. </beans>return "success";
  28.     }
复制代码

  • 除了HttpServletRequest, HttpServletResponse 还可以其它对象也可以这样的情势获取

  • HttpSession、java.security.Principal,InputStream,OutputStream,Reader,Writer

模型数据

数据放入Request域

通过HttpServletRequest放入Request域


  • 通过HttpServletRequest放入Request域是默认机制
  1. @RequestMapping(value = "/vote05")
  2.     public String test05(Master master) {
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>return "vote_ok";
  8.     }
复制代码

  • 当我们提交的数据和对象名保持一致,那么SpringMVC回自动封装成一个对象【在前面 获取javabean 情势的数据 讲过】
  • SpringMVC还会有一个机制,会自动将封装的这个对象【model模型】放入Request域
  • 也可以手动将对象放入Request域
  • 会以 k-v 的情势放入Request域,k 是类名首字母小写,v 是对象


  • 如果我们需要向Request域中添加新的属性/对象
    1. request.setAttribute("address","beijing");
    复制代码
  • 如果我们要修改默认机制自动放入的对象的属性
  1. master.setName("pp");
复制代码
通过请求的方法参数Map放入Request域
  1. @RequestMapping(value = "/vote06")
  2.     public String test06(Master master, Map<String,Object> map) {
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>map.put("address","tianjing");
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>map.put("master",null);
  13. <?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>//返回到一个结果
  18. <?xml version="1.0" encoding="UTF-8" ?>
  19. <beans>
  20.    
  21.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  22. </beans>return "vote_ok";
  23.     }
复制代码

  • SpringMVC会遍历Map,然会将map中的 k-v 存放到Request域
  • 如果 map.put("master",null); 会覆盖默认机制的master,为null
通过返回ModelAndView对象实现Request域数据
  1. @RequestMapping(value = "/vote07")
  2.     public ModelAndView test07(Master master) {
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>ModelAndView modelAndView = new ModelAndView();
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>modelAndView.addObject("address","shanghai");
  13. <?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>modelAndView.addObject("master",null);
  18. <?xml version="1.0" encoding="UTF-8" ?>
  19. <beans>
  20.    
  21.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  22. </beans>//指定跳转的视图名称
  23. <?xml version="1.0" encoding="UTF-8" ?>
  24. <beans>
  25.    
  26.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  27. </beans>modelAndView.setViewName("vote_ok");
  28. <?xml version="1.0" encoding="UTF-8" ?>
  29. <beans>
  30.    
  31.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  32. </beans>return modelAndView;
  33.     }
复制代码

  • SpringMVC会遍历ModelAndView,然会将ModelAndView中的 k-v 存放到Request域
  • 如果 modelAndView.addObject("master",null); 会覆盖默认机制的master,为null
注意事项:

  • 从本质上看,请求响应的方法 return "xx",是返回了一个字符串,其实本质是返回一个ModelAndView对象,只是默认被封装起来了
  • ModelAndView对象既可以包罗model数据,也可以包罗视图信息
  • ModelAndView对象的addObject("","");方法 可以添加key -value数据,默认在Request域中
  • ModelAndView对象setView方法是指定 视图名称
数据放入Session域
  1. @RequestMapping(value = "/vote08")
  2.     public String test08(Master master,HttpSession session){
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>session.setAttribute("master",master);
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>session.setAttribute("address","guangzhou");
  13. <?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>return "vote_ok";
  18.     }
复制代码
@ModelAttribute
  1. @ModelAttribute
  2.     public void prepareModel(){
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>System.out.println("prepareModel()-----完成准备工作-----");
  8.     }
复制代码

  • 在某个方法上加上 @ModelAttribute 注解,那么在调用该Handler的任何方法都会调用这个方法
  • 类似Aop的前置关照
视图和视图解析器

基本介绍


  • 在springMVC 中的目的方法最终返回都是一个视图(有各种视图).
  • 返回的视图都会由一个视图解析器来处置处罚(视图解析器有许多种)
自定义视图


  • 在默认情况下,我们都是返回默认的视图, 然后这个返回的视图交由SpringMVC 的 InternalResourceViewResolver 视图处置处罚器来处置处罚的
​<bean >
        <property name="order" value="99"></property>
</bean><bean >
        <property name="order" value="99"></property>
</bean>前缀 value="/WEB-INF/pages/"  和 后缀 value=".jsp" 之后会拼接 返回给视图解析器的返回值
  1.     <bean >
  2.    
  3.    
  4. <?xml version="1.0" encoding="UTF-8" ?>
  5. <beans>
  6.    
  7.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  8. </beans><property name="prefix" value="/WEB-INF/pages/"/>
  9. <?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans><property name="suffix" value=".jsp"/>
  14.     </bean>
复制代码
  1. 2. 在实际开发中,我们有时需要自定义视图,这样可以满足更多更复杂的需求.
复制代码
需要在spring配置文件 , 增加自定义视图解析器
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean>
复制代码

  • name="order" :表示给这个解析器设置优先级,
  • 我们自己的视图解析优先级高,Order 值越小,优先级越高
编写自己的视图


  • 继承 AbstractView 就可以作为一个视图使用
  • @Component(value = "myView")会作为id= myView 的一个组件 注入到容器中
  1. @Component(value = "zyView")
  2. public class MyView extends AbstractView {
  3.     @Override
  4.     protected void renderMergedOutputModel(Map<String, Object> map,
  5. HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
  6. <?xml version="1.0" encoding="UTF-8" ?>
  7. <beans>
  8.    
  9.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  10. </beans>//该方法完成视图渲染
  11. <?xml version="1.0" encoding="UTF-8" ?>
  12. <beans>
  13.    
  14.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  15. </beans>//并且可以确定我们要跳转的页面 /WEB-INF/pages/my_view.jsp
  16. <?xml version="1.0" encoding="UTF-8" ?>
  17. <beans>
  18.    
  19.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  20. </beans>System.out.println("进入到自己的视图..");
  21. <?xml version="1.0" encoding="UTF-8" ?>
  22. <beans>
  23.    
  24.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  25. </beans>//请求转发到 /WEB-INF/pages/my_view.jsp
  26. <?xml version="1.0" encoding="UTF-8" ?>
  27. <beans>
  28.    
  29.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  30. </beans>//第一个斜杠会解析成 工程路径-> springmvc/
  31. <?xml version="1.0" encoding="UTF-8" ?>
  32. <beans>
  33.    
  34.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  35. </beans>httpServletRequest.getRequestDispatcher("/WEB-INF/pages/my_view.jsp")
  36. <mvc:interceptor>
  37.     <mvc:mapping path="/h*"/>
  38.     <mvc:exclude-mapping path="/hello"/>
  39.     <ref bean="myInterceptor02"/>
  40. </mvc:interceptor>    .forward(httpServletRequest,httpServletResponse);
  41.     }
  42. }
复制代码
进行跳转
  1. @RequestMapping("/goods")
  2. @Controller
  3. public class GoodsHandler {
  4.     @RequestMapping(value = "/buy")
  5.     public String buy() {
  6. <?xml version="1.0" encoding="UTF-8" ?>
  7. <beans>
  8.    
  9.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  10. </beans>System.out.println("--buy()被调用--");
  11.        return "zyView";
  12.     }
  13. }
复制代码
自定义视图小结


  • 自定义视图: 创建一个View 的bean, 该bean 需要继承自AbstractView, 并实现 renderMergedOutputModel 方法.
  • 并把自定义View 参加到IOC 容器中
  • 自定义视图的视图处置处罚器,使用BeanNameViewResolver, 这个视图处置处罚器也需要配置到ioc 容器
  • BeanNameViewResolver 的调用优先级需要设置一下,设置order 比Integer.MAX_VAL 小的值. 以确保其在InternalResourceViewResolver 之前被调用
自定义视图-工作流程


  • SpringMVC 调用目的方法, 返回自定义View 在IOC 容器中的id
  • SpringMVC 调用BeanNameViewResolver 解析视图: 从IOC 容器中获取返回id 值对应的bean, 即自定义的View 的对象
  • SpringMVC 调用自定义视图的renderMergedOutputModel 方法渲染视图
  • 如果在SpringMVC 调用目的方法, 返回自定义View 在IOC 容器中的id不存在, 则仍然按照默认的视图处置处罚器机制处置处罚
自定义解析器的实行流程-源码
  1. /** * 自定义解析器的实行流程 *  1. *    @RequestMapping(value = "/buy") *     public String buy() { *<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans> System.out.println("--buy()被调用--"); *<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>return "zyView";  --> *     } *  2. *  ApplicationContext context = obtainApplicationContext(); * <bean >
  10.         <property name="order" value="99"></property>
  11. </bean><bean >
  12.         <property name="order" value="99"></property>
  13. </bean>if (!context.containsBean(viewName)) {//判断viewName是否在容器中 * <bean >
  14.         <property name="order" value="99"></property>
  15. </bean><bean >
  16.         <property name="order" value="99"></property>
  17. </bean><bean >
  18.         <property name="order" value="99"></property>
  19. </bean>// Allow for ViewResolver chaining... * <bean >
  20.         <property name="order" value="99"></property>
  21. </bean><bean >
  22.         <property name="order" value="99"></property>
  23. </bean><bean >
  24.         <property name="order" value="99"></property>
  25. </bean>return null; *<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor>    } * <bean >
  30.         <property name="order" value="99"></property>
  31. </bean><bean >
  32.         <property name="order" value="99"></property>
  33. </bean>if (!context.isTypeMatch(viewName, View.class)) {//判断是否继承了 AbstractView 实际上是判断是否实现了View接口 因为AbstractView实现了View接口 * <bean >
  34.         <property name="order" value="99"></property>
  35. </bean><bean >
  36.         <property name="order" value="99"></property>
  37. </bean><bean >
  38.         <property name="order" value="99"></property>
  39. </bean>if (logger.isDebugEnabled()) { * <bean >
  40.         <property name="order" value="99"></property>
  41. </bean><bean >
  42.         <property name="order" value="99"></property>
  43. </bean><bean >
  44.         <property name="order" value="99"></property>
  45. </bean><bean >
  46.         <property name="order" value="99"></property>
  47. </bean>logger.debug("Found bean named '" + viewName + "' but it does not implement View"); *<mvc:interceptor>
  48.     <mvc:mapping path="/h*"/>
  49.     <mvc:exclude-mapping path="/hello"/>
  50.     <ref bean="myInterceptor02"/>
  51. </mvc:interceptor>} * <bean >
  52.         <property name="order" value="99"></property>
  53. </bean><bean >
  54.         <property name="order" value="99"></property>
  55. </bean><bean >
  56.         <property name="order" value="99"></property>
  57. </bean>// Since we're looking into the general ApplicationContext here, * <bean >
  58.         <property name="order" value="99"></property>
  59. </bean><bean >
  60.         <property name="order" value="99"></property>
  61. </bean><bean >
  62.         <property name="order" value="99"></property>
  63. </bean>// let's accept this as a non-match and allow for chaining as well... * <bean >
  64.         <property name="order" value="99"></property>
  65. </bean><bean >
  66.         <property name="order" value="99"></property>
  67. </bean><bean >
  68.         <property name="order" value="99"></property>
  69. </bean>return null; *<?xml version="1.0" encoding="UTF-8" ?>
  70. <beans>
  71.    
  72.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  73. </beans>} * <bean >
  74.         <property name="order" value="99"></property>
  75. </bean><bean >
  76.         <property name="order" value="99"></property>
  77. </bean>return context.getBean(viewName, View.class);    --> * <bean >
  78.         <property name="order" value="99"></property>
  79. </bean>} * <bean >
  80.         <property name="order" value="99"></property>
  81. </bean>3. * <bean >
  82.         <property name="order" value="99"></property>
  83. </bean> protected void renderMergedOutputModel(Map map, * HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { * *<?xml version="1.0" encoding="UTF-8" ?>
  84. <beans>
  85.    
  86.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  87. </beans> //该方法完成视图渲染 *<?xml version="1.0" encoding="UTF-8" ?>
  88. <beans>
  89.    
  90.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  91. </beans> //而且可以确定我们要跳转的页面 /WEB-INF/pages/my_view.jsp *<?xml version="1.0" encoding="UTF-8" ?>
  92. <beans>
  93.    
  94.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  95. </beans> System.out.println("进入到自己的视图.."); * *<?xml version="1.0" encoding="UTF-8" ?>
  96. <beans>
  97.    
  98.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  99. </beans> //请求转发到 /WEB-INF/pages/my_view.jsp *<?xml version="1.0" encoding="UTF-8" ?>
  100. <beans>
  101.    
  102.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  103. </beans> //第一个斜杠会解析成 工程路径-> springmvc/ *<?xml version="1.0" encoding="UTF-8" ?>
  104. <beans>
  105.    
  106.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  107. </beans> httpServletRequest.getRequestDispatcher("/WEB-INF/pages/my_view.jsp") *<mvc:interceptor>
  108.     <mvc:mapping path="/h*"/>
  109.     <mvc:exclude-mapping path="/hello"/>
  110.     <ref bean="myInterceptor02"/>
  111. </mvc:interceptor>     .forward(httpServletRequest,httpServletResponse); --> *     } * } * <bean >
  112.         <property name="order" value="99"></property>
  113. </bean>4. * <bean >
  114.         <property name="order" value="99"></property>
  115. </bean>[size=6]进入到my_view页面[/size]
  116. * 是从自定义视图来的...
  117. * * */
复制代码
默认解析器的实行流程-源码
  1. /** * 默认解析器的实行流程 * 1. * public String buy() { *<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans> System.out.println("--buy()被调用--"); *<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>return "zyView";-> *     } * 2. * public InternalResourceViewResolver(String prefix, String suffix) { * <bean >
  10.         <property name="order" value="99"></property>
  11. </bean><bean >
  12.         <property name="order" value="99"></property>
  13. </bean>this(); * <bean >
  14.         <property name="order" value="99"></property>
  15. </bean><bean >
  16.         <property name="order" value="99"></property>
  17. </bean>setPrefix(prefix);//用于拼接 * <bean >
  18.         <property name="order" value="99"></property>
  19. </bean><bean >
  20.         <property name="order" value="99"></property>
  21. </bean>setSuffix(suffix);//用于拼接 *  } * 3. * protected AbstractUrlBasedView buildView(String viewName) throws Exception { * <bean >
  22.         <property name="order" value="99"></property>
  23. </bean><bean >
  24.         <property name="order" value="99"></property>
  25. </bean>InternalResourceView view = (InternalResourceView) super.buildView(viewName);//调用super.buildView(viewName) * <bean >
  26.         <property name="order" value="99"></property>
  27. </bean><bean >
  28.         <property name="order" value="99"></property>
  29. </bean>if (this.alwaysInclude != null) { * <bean >
  30.         <property name="order" value="99"></property>
  31. </bean><bean >
  32.         <property name="order" value="99"></property>
  33. </bean><bean >
  34.         <property name="order" value="99"></property>
  35. </bean>view.setAlwaysInclude(this.alwaysInclude); *<mvc:interceptor>
  36.     <mvc:mapping path="/h*"/>
  37.     <mvc:exclude-mapping path="/hello"/>
  38.     <ref bean="myInterceptor02"/>
  39. </mvc:interceptor>    } * <bean >
  40.         <property name="order" value="99"></property>
  41. </bean><bean >
  42.         <property name="order" value="99"></property>
  43. </bean>view.setPreventDispatchLoop(true); * <bean >
  44.         <property name="order" value="99"></property>
  45. </bean><bean >
  46.         <property name="order" value="99"></property>
  47. </bean>return view; * } * 4. * 找不到 报错404 */
复制代码
找不到自定义解析器 会调用默认解析器
  1. /** * 找不到自定义解析器 会调用默认解析器 * 1. * public String buy() { *<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans> System.out.println("--buy()被调用--"); *<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>return "zyView"; --> *     } * 2. *  ApplicationContext context = obtainApplicationContext(); * <bean >
  10.         <property name="order" value="99"></property>
  11. </bean><bean >
  12.         <property name="order" value="99"></property>
  13. </bean>if (!context.containsBean(viewName)) {//找不到返回null * <bean >
  14.         <property name="order" value="99"></property>
  15. </bean><bean >
  16.         <property name="order" value="99"></property>
  17. </bean><bean >
  18.         <property name="order" value="99"></property>
  19. </bean>// Allow for ViewResolver chaining... * <bean >
  20.         <property name="order" value="99"></property>
  21. </bean><bean >
  22.         <property name="order" value="99"></property>
  23. </bean><bean >
  24.         <property name="order" value="99"></property>
  25. </bean>return null;--> *     } * 3. *  if (this.viewResolvers != null) { * <bean >
  26.         <property name="order" value="99"></property>
  27. </bean><bean >
  28.         <property name="order" value="99"></property>
  29. </bean><bean >
  30.         <property name="order" value="99"></property>
  31. </bean>for (ViewResolver viewResolver : this.viewResolvers) { //遍历解析器 * <bean >
  32.         <property name="order" value="99"></property>
  33. </bean><bean >
  34.         <property name="order" value="99"></property>
  35. </bean><bean >
  36.         <property name="order" value="99"></property>
  37. </bean><bean >
  38.         <property name="order" value="99"></property>
  39. </bean>View view = viewResolver.resolveViewName(viewName, locale);//此时以及走默认解析器那一套了 * <bean >
  40.         <property name="order" value="99"></property>
  41. </bean><bean >
  42.         <property name="order" value="99"></property>
  43. </bean><bean >
  44.         <property name="order" value="99"></property>
  45. </bean><bean >
  46.         <property name="order" value="99"></property>
  47. </bean>if (view != null) { * <bean >
  48.         <property name="order" value="99"></property>
  49. </bean><bean >
  50.         <property name="order" value="99"></property>
  51. </bean><bean >
  52.         <property name="order" value="99"></property>
  53. </bean><bean >
  54.         <property name="order" value="99"></property>
  55. </bean><bean >
  56.         <property name="order" value="99"></property>
  57. </bean>return view;//进行拼接前缀和后缀 但找不到 *<mvc:interceptor>
  58.     <mvc:mapping path="/h*"/>
  59.     <mvc:exclude-mapping path="/hello"/>
  60.     <ref bean="myInterceptor02"/>
  61. </mvc:interceptor>} *    } *  4. *  拼接后找不到 报错 404 */
复制代码
默认解析器一旦解析  不会去自定义解析器


  • 因为默认解析器会拼接 view != null 就return了
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean> * if (this.viewResolvers != null) {     * <bean >
  4.         <property name="order" value="99"></property>
  5. </bean><bean >
  6.         <property name="order" value="99"></property>
  7. </bean><bean >
  8.         <property name="order" value="99"></property>
  9. </bean>for (ViewResolver viewResolver : this.viewResolvers) {     * <bean >
  10.         <property name="order" value="99"></property>
  11. </bean><bean >
  12.         <property name="order" value="99"></property>
  13. </bean><bean >
  14.         <property name="order" value="99"></property>
  15. </bean><bean >
  16.         <property name="order" value="99"></property>
  17. </bean>View view = viewResolver.resolveViewName(viewName, locale);     * <bean >
  18.         <property name="order" value="99"></property>
  19. </bean><bean >
  20.         <property name="order" value="99"></property>
  21. </bean><bean >
  22.         <property name="order" value="99"></property>
  23. </bean><bean >
  24.         <property name="order" value="99"></property>
  25. </bean>if (view != null) {     * <bean >
  26.         <property name="order" value="99"></property>
  27. </bean><bean >
  28.         <property name="order" value="99"></property>
  29. </bean><bean >
  30.         <property name="order" value="99"></property>
  31. </bean><bean >
  32.         <property name="order" value="99"></property>
  33. </bean><bean >
  34.         <property name="order" value="99"></property>
  35. </bean>return view;     *<mvc:interceptor>
  36.     <mvc:mapping path="/h*"/>
  37.     <mvc:exclude-mapping path="/hello"/>
  38.     <ref bean="myInterceptor02"/>
  39. </mvc:interceptor>  }     *   }
复制代码
目的方法直接指定转发或重定向


  • 默认返回的方式是请求转发,然后用视图处置处罚器进行处置处罚
  1. @RequestMapping(value = "/buy")
  2.     public String buy(){
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>return "success";
  8.     }
复制代码

  • 也可以在目的方法直接指定重定向或转发的url 地址
请求转发:return "forword:路径"
  1. return "forword:/WEB-INF/pages/my_view.jsp"
复制代码
重定向:return "redirect:路径"
  1. return "redirect:login.jsp"
复制代码
注意事项:

  • 对于重定向,不能重定向到WEB-INF目录下
    重定向在响应头返回的URL中是<?xml version="1.0" encoding="UTF-8" ?>
    <beans>
       
        <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    </beans>   /工程路径/login.jsp【此时,浏览器会将第一个 / 处置处罚成 IP:端口/工程路径/login.jsp】
  • 对于请求转发,是在服务器内部进行,第一个 / 解析成 工程路径,进行转发
数据格式化

基本介绍

引出:在我们提交数据(比如表单时)SpringMVC 怎样对提交的数据进行转换和处置处罚的??

  • 基本数据类型可以和字符串之间自动完成转换
  • Spring MVC 上下文中内建了许多转换器,可完成大多数Java 类型的转换工作
基本数据类型和字符串自动转换
  1. <form:form action="save" method="post" modelAttribute="monster">
  2.     妖怪名字: <form:input path="name"/> <form:errors path="name"/> <br><br>
  3.     妖怪年龄~: <form:input path="age"/> <form:errors path="age"/><br><br>
  4.     电子邮件: <form:input path="email"/> <form:errors path="email"/><br><br>
  5.     妖怪生日: <form:input path="birthday"/> <form:errors path="birthday"/>要求以"9999-11-11"的形式<br><br>
  6.     妖怪薪水: <form:input path="salary"/> <form:errors path="salary"/>要求以"123,890.12"的形式<br><br>
  7.     <input type="submit" value="添加妖怪"/>
  8. </form:form>
复制代码

  • SpringMVC 表单标签在显示之前必须在request 中有一个bean, 该bean 的属性和表单标签的字段要对应!
  • request 中的key 为: form 标签的modelAttribute 属性值, 比如这里的monsters
  • SpringMVC 的form:form 标签的action 属性值中的/ 不代表WEB 应用的根目录.
  1. @RequestMapping(value = "/addMonsterUI")
  2.     public String addMonsterUI(Map<String, Object> map) {
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>//这里需要给request 增加一个monster , 因为jsp 页面的modelAttribute="monster"需要
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>//是springMVC 的内部的检测机制即使是一个空的也需要,否则报错
  13. <?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>map.put("monster", new Monster());
  18. <?xml version="1.0" encoding="UTF-8" ?>
  19. <beans>
  20.    
  21.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  22. </beans>return "datavalid/monster_addUI";
  23.     }
复制代码
分析:

  • 当我们在浏览器发送 age=10 时,会把10转换成String类型,到达后端后,又会把String转成 int/Integer
  • 而发送 age=aaa 时,会把aaa转成 string类型,到达后端后,把String类型 的 aaa转换成 int/Integer,此时会报错
特别数据类型和字符串间的转换


  • 特别数据类型和字符串之间的转换使用注解(比如日期,规定格式的小数比如货币情势等)
  • 对于日期和货币可以使用@DateTimeFormat 和@NumberFormat 注解. 把这两个注解标志在字段上即可.(JavaBean上)
    1. @DateTimeFormat(pattern = "yyy-MM-dd")
    2.     private Date birthday;
    复制代码
验证国际化


  • 对输入的数据(比如表单数据),进行必要的验证,并给出相应的提示信息
  • 对于验证表单数据,springMVC 提供了许多实用的注解, 这些注解由JSR 303 验证框架提供.
JSR 303 验证框架


  • JSR 303 是Java 为Bean 数据正当性校验提供的标准框架,它已经包罗在JavaEE 中
  • JSR 303 通过在Bean 属性上标注类似于@NotNull、@Max 等标准的注解指定校验规则,
    并通过标准的验证接口对Bean 进行验证
  • JSR 303 提供的基本验证注解有:

Hibernate Validator 扩展注解


  • Hibernate Validator 和Hibernate 没有关系,只是JSR 303 实现的一个扩展.
  • Hibernate Validator 是JSR 303 的一个参考实现,除支持全部标准的校验注解外,它还支
    持以下的扩展注解:
  • 扩展注解有如下:
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean>@NotNull(message = "年龄必须1-100")    @Range(min = 1,max = 100)    private Integer age;    @NotNull    private String name ;    @NotNull(message = "生日必须符合格式")    @DateTimeFormat(pattern = "yyy-MM-dd")
  4.     private Date birthday;    @NotNull(message = "salary必须符合格式")    @NumberFormat(pattern = "###,###.##")    private Float salary;
复制代码
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean>@RequestMapping(value = "/save")    public String save(@Valid Monster monster, Errors errors, Map map) {}
复制代码

  • @Valid Monster monster:表示对monster 接收的数据进行校验
  • Errors errors: 表示如果校验出现错误,将校验的错误信息保存到 errors 中
  • Map map:如果校验出现错误,会将校验的错误信息保存到map,而且同时保存 monster对象


  • 在前端使用 回显错误信息
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean>妖怪名字:   
  4.     妖怪年龄~:  
  5.     电子邮件:  
  6.     妖怪生日:  要求以"9999-11-11"的情势
  7.     妖怪薪水:  要求以"123,890.12"的情势
复制代码
自定义验证错误信息

1.需要在Spring配置文件中配置相关bean
  1.     <bean id="messageSource" class=
  2. <mvc:interceptor>
  3.     <mvc:mapping path="/h*"/>
  4.     <mvc:exclude-mapping path="/hello"/>
  5.     <ref bean="myInterceptor02"/>
  6. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  7. <?xml version="1.0" encoding="UTF-8" ?>
  8. <beans>
  9.    
  10.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  11. </beans>
  12. <?xml version="1.0" encoding="UTF-8" ?>
  13. <beans>
  14.    
  15.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  16. </beans><property name="basename" value="i18n"></property>
  17.     </bean>
复制代码
2.需要在src目录下创建 i18nxxx.properties去读取错误信息
  1. NotEmpty.monster.name=\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a
  2. typeMismatch.monster.age=\u5e74\u9f84\u8981\u6c42\u5728\u0031\u002d\u0031\u0035\u0030\u4e4b\u95f4
  3. typeMismatch.monster.birthday=\u751f\u65e5\u683c\u5f0f\u4e0d\u6b63\u786e
  4. typeMismatch.monster.salary=\u85aa\u6c34\u683c\u5f0f\u4e0d\u6b63\u786e
复制代码
3.用工具将希望自定义的错误信息转换成Unicode编码填入i18nxxx.properties

注意事项


  • 在需要验证的Javabean/POJO 的字段上加上相应的验证注解.
  • 目的方法上,在JavaBean/POJO 类型的参数前, 添加@Valid 注解. 告知SpringMVC该bean 是需要验证的
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean>@RequestMapping(value = "/save")    public String save(@Valid Monster monster, Errors errors, Map map) {}
复制代码

  • 在@Valid 注解之后, 添加一个Errors 或BindingResult 类型的参数, 可以获取到验证的错误信息
  • 需要使用 标签来显示错误消息, 这个标签,需要写在form:form 标签内生效.
  1. <form:form action="save" method="post" modelAttribute="monster">
  2.     妖怪名字: <form:input path="name"/> <form:errors path="name"/> <br><br>
  3. </form:form>
复制代码

  • 错误消息的国际化文件i18n.properties , 中文需要是Unicode 编码,使用工具转码.
    格式: 验证规则.表单modelAttribute 值.属性名=消息信息
    NotEmpty.monster.name=\u540D\u5B57\u4E0D\u80FD\u4E3A\u7A7A
    typeMismatch.monster.age=\u7C7B\u578B\u4E0D\u5339\u914D
  • 注解@NotNull 和@NotEmpty 的区别分析


  • @NotEmpty 是判断 null 的 而且可以接收 任何类型
  • @NotNull  是判断null 和 empty的,接收String,collection,map和array
  • 如果是字符串验证空, 建议使用@NotEmpty

  • SpingMVC 验证时,会根据差别的验证错误, 返回对应的信息
注解组合使用


  • 使用@NotNull + @Range 组合使用
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean>@NotNull(message = "年龄必须1-100")    @Range(min = 1,max = 100)    private Integer age;
复制代码
取消属性绑定 @InitBinder 注解


  • 不希望接收到某个表单对应的属性的值,则可以通过@InitBinder 注解取消绑定.

  • 使用@InitBinder 标识的该方法,可以对WebDataBinder 对象进行初始化。
  • WebDataBinder 是DataBinder 的子类,用于完成由表单字段到JavaBean 属性的绑定
  • @InitBinder 方法不能有返回值,它必须声明为void。
  • @InitBinder 方法的参数通常是是WebDataBinder
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean>@InitBinder    public void initBinder(WebDataBinder webDataBinder){<?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>webDataBinder.setDisallowedFields("name");//表示取消属性name的绑定; 这里可以填写多个字段    }
复制代码

  • 取消属性的绑定,那么在JavaBean中的校验注解也应该去掉
中文乱码问题处置处罚


  • Spring提供的过滤器处置处罚中文
  1. <filter>
  2. <?xml version="1.0" encoding="UTF-8" ?>
  3. <beans>
  4.    
  5.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  6. </beans><filter-name>CharacterEncodingFilter</filter-name>
  7. <?xml version="1.0" encoding="UTF-8" ?>
  8. <beans>
  9.    
  10.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  11. </beans><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  12. <?xml version="1.0" encoding="UTF-8" ?>
  13. <beans>
  14.    
  15.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  16. </beans><init-param>
  17. <mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor><param-name>encoding</param-name>
  22. <mvc:interceptor>
  23.     <mvc:mapping path="/h*"/>
  24.     <mvc:exclude-mapping path="/hello"/>
  25.     <ref bean="myInterceptor02"/>
  26. </mvc:interceptor><param-value>utf-8</param-value>
  27. <?xml version="1.0" encoding="UTF-8" ?>
  28. <beans>
  29.    
  30.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  31. </beans></init-param>
  32. </filter>
  33. <filter-mapping>
  34. <?xml version="1.0" encoding="UTF-8" ?>
  35. <beans>
  36.    
  37.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  38. </beans><filter-name>CharacterEncodingFilter</filter-name>
  39. <?xml version="1.0" encoding="UTF-8" ?>
  40. <beans>
  41.    
  42.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  43. </beans><url-pattern>/*</url-pattern>
  44. </filter-mapping>
复制代码
处置处罚JSON格式

@ResponseBody


  • 服务器 -----JSON数据-----> 客户端/浏览器
  1. @RequestMapping(value = "/json/dog")
  2.     @ResponseBody
  3.     public Dog getJson(){
  4. <?xml version="1.0" encoding="UTF-8" ?>
  5. <beans>
  6.    
  7.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  8. </beans>Dog dog = new Dog("大黄", "贝加尔");
  9. <?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>return dog;
  14.     }
复制代码
@RequestBody

客户端/浏览器-----JSON数据-----> 服务器
  1. @RequestMapping(value = "/save2")
  2. @ResponseBody
  3. public User save2(@RequestBody User user){
  4.     System.out.println("user= "+user);
  5.     return user;
  6. }
复制代码

  • 将客户端/浏览器发送的json字符串数据封装成 JavaBean对象
  • 再把这个 JavaBean对象 以 json对象情势返回
  • (@RequestBody User user)在形参上指定
  • SpringMVC就会将提交的json字符串数据填充给指定JavaBean
注意事项


  • 目的方法正常返回json需要的数据,可以是对象也可以是集合
  • @ResponseBody可以写在类上,这样对该类全部的方法生效
  • @ResponseBody + @Controller 可以直接写成@RestController
HttpMessageConverter


  • SpringMVC 处置处罚JSON-底层实现是依靠HttpMessageConverter来进行转换的
工作机制简图



  • 使用HttpMessageConverter 将请求信息转化并绑定到处置处罚方法的入参中, 或将响应结果转为对应类型的响应信息,Spring 提供了两种途径:

    • 使用@RequestBody / @ResponseBody 对目的方法进行标注
    • 使用HttpEntity / ResponseEntity 作为目的方法的入参或返回值

  • 当控制器处置处罚方法使用到@RequestBody/@ResponseBody 或HttpEntity/ResponseEntity 时, Spring 首先根据请求头或响应头的Accept 属性选择匹配的HttpMessageConverter, 进而根据参数类型或泛型类型的过滤得到匹配的HttpMessageConverter, 若找不到可用的HttpMessageConverter 将报错
SpringMVC文件上传


  • 在SpringMVC 中,通过返回ResponseEntity的类型,可以实现文件下载的功能
  • 需要构建 ResponseEntity 对象,需要1.得到http响应头<?xml version="1.0" encoding="UTF-8" ?>
    <beans>
       
        <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    </beans> 2.http响应状态<?xml version="1.0" encoding="UTF-8" ?>
    <beans>
       
        <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    </beans>3.下载文件的数据
  1. @RequestMapping(value="/downFile")
  2.     public ResponseEntity<byte[]> downFile(HttpSession session) throws  Exception{
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>//1.先获取到要下载 的 InputStream
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>InputStream resourceAsStream =
  13. <mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor>    session.getServletContext().getResourceAsStream("/img/1.jpg");
  18. <?xml version="1.0" encoding="UTF-8" ?>
  19. <beans>
  20.    
  21.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  22. </beans>//2.开辟存放文件的byte数组 -> 支持二进制数据
  23. <?xml version="1.0" encoding="UTF-8" ?>
  24. <beans>
  25.    
  26.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  27. </beans>//resourceAsStream.available() 返回资源文件的大小
  28. <?xml version="1.0" encoding="UTF-8" ?>
  29. <beans>
  30.    
  31.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  32. </beans>byte[] bytes = new byte[resourceAsStream.available() ];
  33. <?xml version="1.0" encoding="UTF-8" ?>
  34. <beans>
  35.    
  36.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  37. </beans>//3. 将要下载的文件数据读入到byte数组
  38. <?xml version="1.0" encoding="UTF-8" ?>
  39. <beans>
  40.    
  41.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  42. </beans>resourceAsStream.read(bytes);
  43. <?xml version="1.0" encoding="UTF-8" ?>
  44. <beans>
  45.    
  46.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  47. </beans>/*
  48. <?xml version="1.0" encoding="UTF-8" ?>
  49. <beans>
  50.    
  51.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  52. </beans>ResponseEntity 的构造器:
  53. <mvc:interceptor>
  54.     <mvc:mapping path="/h*"/>
  55.     <mvc:exclude-mapping path="/hello"/>
  56.     <ref bean="myInterceptor02"/>
  57. </mvc:interceptor>public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatus status) {
  58. <mvc:interceptor>
  59.     <mvc:mapping path="/h*"/>
  60.     <mvc:exclude-mapping path="/hello"/>
  61.     <ref bean="myInterceptor02"/>
  62. </mvc:interceptor>this(body, headers, (Object) status);
  63. <mvc:interceptor>
  64.     <mvc:mapping path="/h*"/>
  65.     <mvc:exclude-mapping path="/hello"/>
  66.     <ref bean="myInterceptor02"/>
  67. </mvc:interceptor>}
  68. <?xml version="1.0" encoding="UTF-8" ?>
  69. <beans>
  70.    
  71.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  72. </beans> */
  73. <?xml version="1.0" encoding="UTF-8" ?>
  74. <beans>
  75.    
  76.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  77. </beans>//准备构造ResponseEntity 对象
  78. <?xml version="1.0" encoding="UTF-8" ?>
  79. <beans>
  80.    
  81.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  82. </beans>//4.构建httpStatus
  83. <?xml version="1.0" encoding="UTF-8" ?>
  84. <beans>
  85.    
  86.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  87. </beans>HttpStatus httpStatus = HttpStatus.OK;
  88. <?xml version="1.0" encoding="UTF-8" ?>
  89. <beans>
  90.    
  91.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  92. </beans>//5.构建http响应头
  93. <?xml version="1.0" encoding="UTF-8" ?>
  94. <beans>
  95.    
  96.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  97. </beans>HttpHeaders headers = new HttpHeaders();
  98. <?xml version="1.0" encoding="UTF-8" ?>
  99. <beans>
  100.    
  101.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  102. </beans>//指定浏览器以附件的形式处理回送数据
  103. <?xml version="1.0" encoding="UTF-8" ?>
  104. <beans>
  105.    
  106.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  107. </beans>headers.add("Content-Disposition","attachment;filename=1.jpg");
  108. <?xml version="1.0" encoding="UTF-8" ?>
  109. <beans>
  110.    
  111.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  112. </beans>ResponseEntity<byte[]> responseEntity =
  113. <mvc:interceptor>
  114.     <mvc:mapping path="/h*"/>
  115.     <mvc:exclude-mapping path="/hello"/>
  116.     <ref bean="myInterceptor02"/>
  117. </mvc:interceptor>    new ResponseEntity<>(bytes, headers, httpStatus);
  118. <?xml version="1.0" encoding="UTF-8" ?>
  119. <beans>
  120.    
  121.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  122. </beans>return responseEntity;
  123.     }
复制代码

  • 文件下载响应头的设置
    content-type 指示响应内容的格式
    content-disposition 指示如那边置处罚响应内容,一样寻常有两种方式:1. inline:直接在页面显示<bean >
            <property name="order" value="99"></property>
    </bean>2.attchment:以附件情势下载
SpringMVC文件上传

基本介绍


  • Spring MVC 为文件上传提供了直接的支持,
  • 这种支持是通过即插即用的MultipartResolver 实现的。
  • Spring 用Jakarta Commons FileUpload 技术实现了一个MultipartResolver 实现类:CommonsMultipartResovler
  • Spring MVC 上下文中默认没有装配MultipartResovler,因此默认情况下不能处置处罚文件的上传工作,
  • 如果想使用Spring 的文件上传功能,需现在上下文中配置MultipartResolver
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean><?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>
复制代码

  • 需要在form表单添加属性 enctype="multipart/form-data"
  1. <form action="<%=request.getContextPath()%>/fileUpload" method="post" enctype="multipart/form-data">
  2.     文件介绍:<input type="text" name="introduce"><br>
  3.     选择文件:<input type="file" name="file"><br>
  4.     <input type="submit" value="上传文件">
  5. </form>
复制代码
文件上传
  1. //编写方法 处置处罚文件上传的请求    @RequestMapping(value = "/fileUpload")    public String fileUpload(@RequestParam(value = "file") MultipartFile file,
  2.     <bean id="messageSource" class=
  3. <mvc:interceptor>
  4.     <mvc:mapping path="/h*"/>
  5.     <mvc:exclude-mapping path="/hello"/>
  6.     <ref bean="myInterceptor02"/>
  7. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans>
  13. <?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans><property name="basename" value="i18n"></property>
  18.     </bean>    HttpServletRequest request, String introduce) throws IOException {<?xml version="1.0" encoding="UTF-8" ?>
  19. <beans>
  20.    
  21.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  22. </beans>//接收到提交的文件名<?xml version="1.0" encoding="UTF-8" ?>
  23. <beans>
  24.    
  25.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  26. </beans>String originalFilename = file.getOriginalFilename();<?xml version="1.0" encoding="UTF-8" ?>
  27. <beans>
  28.    
  29.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  30. </beans>System.out.println("提交的文件名= " + originalFilename);<?xml version="1.0" encoding="UTF-8" ?>
  31. <beans>
  32.    
  33.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  34. </beans>System.out.println("文件介绍= " + introduce);<?xml version="1.0" encoding="UTF-8" ?>
  35. <beans>
  36.    
  37.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  38. </beans>//获取到文件保存的目的位置/路径<?xml version="1.0" encoding="UTF-8" ?>
  39. <beans>
  40.    
  41.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  42. </beans>String filePath =<mvc:interceptor>
  43.     <mvc:mapping path="/h*"/>
  44.     <mvc:exclude-mapping path="/hello"/>
  45.     <ref bean="myInterceptor02"/>
  46. </mvc:interceptor>    request.getServletContext().getRealPath("/img/" + originalFilename);<?xml version="1.0" encoding="UTF-8" ?>
  47. <beans>
  48.    
  49.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  50. </beans>//创建文件<?xml version="1.0" encoding="UTF-8" ?>
  51. <beans>
  52.    
  53.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  54. </beans>File saveToFile = new File(filePath);<?xml version="1.0" encoding="UTF-8" ?>
  55. <beans>
  56.    
  57.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  58. </beans>//将上传的文件转存到 saveToFile<?xml version="1.0" encoding="UTF-8" ?>
  59. <beans>
  60.    
  61.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  62. </beans>file.transferTo(saveToFile);<?xml version="1.0" encoding="UTF-8" ?>
  63. <beans>
  64.    
  65.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  66. </beans>return "success";    }
复制代码
拦截器

基本介绍


  • Spring MVC 也可以使用拦截器对请求进行拦截处置处罚,
  • 用户可以自定义拦截器来实现特定的功能.
  • 自定义的拦截器必须实现HandlerInterceptor 接口
自定义拦截器的三个方法


  • preHandle():这个方法在业务处置处罚器处置处罚请求之前被调用,在该方法中对用户请求request 进行处置处罚。
  • postHandle():这个方法在目的方法处置处罚完请求后实行
  • afterCompletion():这个方法在完全处置处罚完请求后被调用,可以在该方法中进行一些资源
    清理的操作。
在Spring配置文件中配置拦截器

默认配置是都全部的目的方法都进行拦截, 也可以指定拦截目的方法, 比如只是拦截hi
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans> //直接引用对应拦截器    <bean >
  6.    
  7.    
  8. <?xml version="1.0" encoding="UTF-8" ?>
  9. <beans>
  10.    
  11.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  12. </beans><property name="prefix" value="/WEB-INF/pages/"/>
  13. <?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans><property name="suffix" value=".jsp"/>
  18.     </bean><?xml version="1.0" encoding="UTF-8" ?>
  19. <beans>
  20.    
  21.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  22. </beans>
复制代码
mvc:mapping 支持通配符, 同时指定不对哪些目的方法进行拦截
  1.     <bean >
  2.    
  3.    
  4. <?xml version="1.0" encoding="UTF-8" ?>
  5. <beans>
  6.    
  7.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  8. </beans><property name="prefix" value="/WEB-INF/pages/"/>
  9. <?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans><property name="suffix" value=".jsp"/>
  14.     </bean><mvc:interceptor>
  15.     <mvc:mapping path="/h*"/>
  16.     <mvc:exclude-mapping path="/hello"/>
  17.     <ref bean="myInterceptor02"/>
  18. </mvc:interceptor>
复制代码

  • 这样配置会拦截h打头的url指定的方法
  1. <mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor>
复制代码

  • 这样配置会拦截h打头的url指定的方法而且排除 url是hello的方法
自定义拦截器实行流程分析图


● 自定义拦截器实行流程分析

  • 如果preHandle 方法返回false, 则不再实行目的方法, 可以在此指定返回页面
  • postHandle 在目的方法被实行后实行. 可以在方法中访问到目的方法返回的 ModelAndView 对象
  • 若preHandle 返回true, 则afterCompletion 方法在渲染视图之后被实行.
  • 若preHandle 返回false, 则afterCompletion 方法不会被调用
  • 在配置拦截器时,可以指定该拦截器对哪些请求生效,哪些请求不生效
注意事项


  • 拦截器需要配置才生效,不配置是不生效的.
  • 如果preHandler() 方法返回了false, 就不会实行目的方法(前提是你的目的方法被拦截了), 程序员可以在这里根据业务需要指定跳转页面.
多个拦截器


注意事项


  • 如果第1 个拦截器的preHandle() 返回false , 后面都不在实行
  • 如果第2 个拦截器的preHandle() 返回false , 就直接实行第1 个拦截器的
    afterCompletion()方法, 如果拦截器更多,规则类似
  • 前面说的规则,都是目的方法被拦截的前提
异常处置处罚

基本介绍


  • Spring MVC 通过HandlerExceptionResolver 处置处罚程序的异常,包括Handler 映射、数据绑定以及目的方法实行时发生的异常。
  • 紧张处置处罚Handler 中用@ExceptionHandler 注解定义的方法。
  • ExceptionHandlerMethodResolver 内部若找不到@ExceptionHandler 注解的话, 会找@ControllerAdvice 类的@ExceptionHandler 注解方法, 这样就相当于一个全局异常处置处罚器
  • 如果不去处置处罚异常,tomcat会默认机制处置处罚,用户看到的页面非常不友好
异常处置处罚的优先级

局部异常 > 全局异常 > SimpleMappingExceptionResolver > tomcat默认机制
局部异常
  1. //局部异常就是直接在这个Handler 中编写即可
  2.     @ExceptionHandler({ArithmeticException.class, NullPointerException.class})
  3.     public String localException(Exception ex,HttpServletRequest request){
  4. <?xml version="1.0" encoding="UTF-8" ?>
  5. <beans>
  6.    
  7.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  8. </beans>System.out.println("异常信息是~" + ex.getMessage());
  9. <?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>//如何将异常的信息带到下一个页面.
  14. <?xml version="1.0" encoding="UTF-8" ?>
  15. <beans>
  16.    
  17.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  18. </beans>request.setAttribute("reason", ex.getMessage());
  19. <?xml version="1.0" encoding="UTF-8" ?>
  20. <beans>
  21.    
  22.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  23. </beans>return "exception_mes";
  24.     }
复制代码
全局异常
  1. @ControllerAdvice//@ControllerAdvice 表示了该注解,就是全局异常
  2. public class MyGlobalException {
  3.     @ExceptionHandler({NumberFormatException.class, ClassCastException.class})
  4.     public String globalException(Exception ex, HttpServletRequest request){
  5. <?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>System.out.println("全局异常处理---"+ex.getMessage());
  10. <?xml version="1.0" encoding="UTF-8" ?>
  11. <beans>
  12.    
  13.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  14. </beans>request.setAttribute("reason",ex.getMessage());
  15. <?xml version="1.0" encoding="UTF-8" ?>
  16. <beans>
  17.    
  18.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  19. </beans>return "exception_mes";
  20.     }
复制代码

  • @ControllerAdvice 表示了该注解,就是全局异常
自定义异常


  • 通过@ResponseStatus 注解, 可以自定义异常
  • 格式:@ResponseStatus(reason = "异常原因",value = httpStatus状态 )
  1. @ResponseStatus(reason = "年龄需要在1-120之间",value = HttpStatus.BAD_REQUEST )
  2. public class AgeException extends RuntimeException{//需要继承RuntimeException/Exception
  3. }
复制代码

  • 自定义异常类需要继承RuntimeException/Exception
  • httpStatus会有许多状态


  • 如果想在其他页面看到reason信息,加上带String构造器即可
    1. public AgeException(String message) {
    2.     super(message);
    3. }
    复制代码
统一处置处罚异常信息

基本介绍


  • 如果希望对全部异常进行统一处置处罚,可以使用SimpleMappingExceptionResolver
  • 它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常
  • 需要在ioc 容器中配置
  1. <mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor><mvc:interceptor>
  6.     <mvc:mapping path="/h*"/>
  7.     <mvc:exclude-mapping path="/hello"/>
  8.     <ref bean="myInterceptor02"/>
  9. </mvc:interceptor>allEx<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor>
复制代码

  • 在这个标签内 就可以配置出现异常需要跳转的页面allEx
  • key="java.lang.Exception" 是异常的范围,这样设置可以对未知异常进行统一处置处罚,也就是全部异常都处置处罚
SpringMVC实行流程以及源码剖析

SpringMVC实行流程表示图


实行流程-源码剖析


  • 发出请求url
    1. protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
    2.    logRequest(request);
    复制代码
  • 调用处置处罚器映射器
    1. //getWebApplicationContext() 就是Spring容器
    2. request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
    3. //走完这一步前端控制器就有了Spring容器
    4. doDispatch(request, response);//进入分发
    5.     2.1 HandlerExecutionChain mappedHandler = null;//有属性 处理器链
    6.     2.2 mappedHandler = getHandler(processedRequest);// mappedHandler中已经有 目标Handler 和 拦截器链
    复制代码
  • 调用处置处罚器适配器
    1. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());//得到处理器适配器
    2. String method = request.getMethod();得到请求方式
    复制代码
  • 调用Handler
    1. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//调用Handler
    2. mav = invokeHandlerMethod(request, response, handlerMethod);
    3. invocableMethod.invokeAndHandle(webRequest, mavContainer);//调用Handler中的目标方法了
    4. ModelAndView modelAndView = new ModelAndView();//到达目标方法
    5. return invoke0(this.method, var1, var2);//目标方法执行完毕返回
    6. return getModelAndView(mavContainer, modelFactory, webRequest);
    7. return mav;//返回给前端处理器
    8. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//回到起点,返回了一个 ModelAndView
    复制代码
  • 调用视图解析器
    1. processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);render(mv, request, response);//进行渲染    //进入render 方法<?xml version="1.0" encoding="UTF-8" ?>
    2. <beans>
    3.    
    4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    5. </beans>String viewName = mv.getViewName();//拿到视图名称<?xml version="1.0" encoding="UTF-8" ?>
    6. <beans>
    7.    
    8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    9. </beans>view = resolveViewName(viewName, mv.getModelInternal(), locale, request);//进行视图解析<?xml version="1.0" encoding="UTF-8" ?>
    10. <beans>
    11.    
    12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    13. </beans>//调用视图解析器<?xml version="1.0" encoding="UTF-8" ?>
    14. <beans>
    15.    
    16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    17. </beans>if (this.viewResolvers != null) {      for (ViewResolver viewResolver : this.viewResolvers) {<?xml version="1.0" encoding="UTF-8" ?>
    18. <beans>
    19.    
    20.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    21. </beans> View view = viewResolver.resolveViewName(viewName, locale);//解析完毕返回视图<?xml version="1.0" encoding="UTF-8" ?>
    22. <beans>
    23.    
    24.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    25. </beans> if (view != null) {<mvc:interceptor>
    26.     <mvc:mapping path="/h*"/>
    27.     <mvc:exclude-mapping path="/hello"/>
    28.     <ref bean="myInterceptor02"/>
    29. </mvc:interceptor>return view;//返回视图给前端控制器<?xml version="1.0" encoding="UTF-8" ?>
    30. <beans>
    31.    
    32.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    33. </beans> }     }   }
    复制代码
  • 视图渲染
    1. view.render(mv.getModelInternal(), request, response);
    2. renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);//渲染合并 输出模型
    3.     //进入方法
    4. <?xml version="1.0" encoding="UTF-8" ?>
    5. <beans>
    6.    
    7.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
    8. </beans>RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);//获得RequestDispatcher
    复制代码
  • 返回响应
    1. rd.forward(request, response);//返回响应
    复制代码
手写SpringMVC底层机制!


  • 前景提要:实现的是SpringMVC焦点机制
  • 对一些细枝末节的代码做了简化,比如字符串的处置处罚...
  • 完成哪些机制

    • 机制一: 通过@RequestMapping ,可以标志一个方法,编写路径url,浏览器就能通过url完成调用
    • 机制二: 进行依靠注入,使之不需要传统的new 一个对象,而是直接从IOC容器中获得
    • 机制三:通过@RequestParam,如果浏览器传递的参数名和目的方法的形参不一致,可以通过value设置进行匹配
    • 机制四:在目的方法完成后,跳转到相关页面 请求转发/重定向
    • 机制五:在目的方法完成后,通过@Response注解,向浏览器发送JSON格式数据

手写添加配置

思路


  • 需要配置pom.xml的依靠
  • 需要写一个Servlet 作为前端控制器
  • 需要配置Web.xml 中的前端控制器 1).url 2)配置spring容器配置文件的classpath:  3)跟随Tomcat 自启动
  • 需要配置spring容器配置文件
  • 需要配置spring容器配置文件 扫描的路径
实现


  • 需要配置pom.xml的依靠
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>  javax.servlet      javax.servlet-api      3.1.0      provided<mvc:interceptor>
  6.     <mvc:mapping path="/h*"/>
  7.     <mvc:exclude-mapping path="/hello"/>
  8.     <ref bean="myInterceptor02"/>
  9. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>dom4j      dom4j      1.1<mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor>    org.apache.commons      commons-lang3      3.12.0   
复制代码

  • 需要写一个Servlet 作为前端控制器
  1. public class ZyDispatcherServlet extends HttpServlet {
  2.     @Override
  3.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  4. <?xml version="1.0" encoding="UTF-8" ?>
  5. <beans>
  6.    
  7.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  8. </beans>System.out.println("ZyDispatcherServlet-doPost--");
  9.     }
  10.     @Override
  11.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. <?xml version="1.0" encoding="UTF-8" ?>
  13. <beans>
  14.    
  15.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  16. </beans>System.out.println("ZyDispatcherServlet-doGet--");
  17.     }
  18. }
复制代码

  • 需要配置Web.xml 中的前端控制器 1).url 2)配置spring容器配置文件的classpath:  3)跟随Tomcat 自启动
  • 需要配置spring容器配置文件 扫描的路径
  1.      ZyDispatcherServlet    com.code_study.zyspringmvc.servlet.ZyDispatcherServlet<mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor>      contextConfigLocation      classpath:zyspringmvc.xml<mvc:interceptor>
  6.     <mvc:mapping path="/h*"/>
  7.     <mvc:exclude-mapping path="/hello"/>
  8.     <ref bean="myInterceptor02"/>
  9. </mvc:interceptor>1<?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>ZyDispatcherServlet    /  
复制代码

  • 需要配置spring容器配置文件
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>
复制代码
完成浏览器可以请求控制层

思路


  • 创建@Controller和自己的Controller
  • 编写工具类XMLParser,解析spring容器配置文件
  • 开发自己的 Spring容器,得到扫描类的全路径列表
  • 开发自己的 前端控制器,实例化对象到容器中
  • 完成请求的URL和控制器方法的映射关系
  • 完成前端控制器分发请求到对应控制器

  • 自定义注解@Controller
  • 创建Controller
  • 需要写一个工具类XMLParser来解析在spring容器配置文件 扫描的路径  的包 返回全部的路径
  • 这个全部的路径 一个split(",")分隔,都进行扫描
  • 需要写自己的 前端控制器
  • 需要写自己的 Spring容器
  • 在前端控制器中 需要添加方法 scanPackage() 扫描 XMLParser 解析出来的路径
  • 在Spring容器中 需要添加一个属性 classFullPathList 来保存扫描出来的类的全路径
  • 需要添加一个属性 ioc 来存放反射生成的bean对象 也就是过滤classFullPathList  中没有@Controller注解的一些路径 并实例化
  • 需要添加类Handler 这个类要保存 一个url 对应的 一个控制器的方法的 映射 ,也就是说,根据这个url,可以找到对应控制器的对应方法
  • 需要添加一个属性 HandlerList 用于 保存Handler 【url 和 控制器的映射】
  • 需要添加三个方法 一个是initHandlerMapping(),完成 url 对应的 一个控制器的方法的 映射,即 将ioc 中bean 中的 方法进行反射,获取url,将 url,method,bean 封装成Handler  放入HandlerList  保存
  • 添加第二个方法 getHandler(),需要将浏览器发送的request请求中的 uri拿出来,遍历HandlerList  进行配对,如果有 就返回对应的Handler
  • 添加第三个方法 executeDispatch(),进行分发处置处罚,需要 调用getHandler() 获取浏览器发送的request请求 对应的 Handler  ,获取Handler  中的method 进行反射调用,method .invoke() 实现分发请求。
实现


  • 自定义注解@Controller
  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface Controller {
  5.     String value() default "";
  6. }
复制代码

  • 创建Controller
  1. @Controller
  2. public class MonsterController {
  3. }
复制代码

  • 需要写一个工具类XMLParser来解析在spring容器配置文件 扫描的路径  的包 返回全部的路径
  1. public class XMLParser {    public static String getBasePackage(String xmlFile){<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>SAXReader saxReader = new SAXReader();<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>ClassLoader classLoader = XMLParser.class.getClassLoader();<?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>InputStream resourceAsStream = classLoader.getResourceAsStream(xmlFile);<?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>try {<mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor>Document document = saxReader.read(resourceAsStream);<mvc:interceptor>
  22.     <mvc:mapping path="/h*"/>
  23.     <mvc:exclude-mapping path="/hello"/>
  24.     <ref bean="myInterceptor02"/>
  25. </mvc:interceptor>Element rootElement = document.getRootElement();<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor>Element element = rootElement.element("component-scan");<mvc:interceptor>
  30.     <mvc:mapping path="/h*"/>
  31.     <mvc:exclude-mapping path="/hello"/>
  32.     <ref bean="myInterceptor02"/>
  33. </mvc:interceptor>String basePackage = element.attribute("base-package").getText();<mvc:interceptor>
  34.     <mvc:mapping path="/h*"/>
  35.     <mvc:exclude-mapping path="/hello"/>
  36.     <ref bean="myInterceptor02"/>
  37. </mvc:interceptor>return basePackage;<?xml version="1.0" encoding="UTF-8" ?>
  38. <beans>
  39.    
  40.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  41. </beans>} catch (DocumentException e) {<mvc:interceptor>
  42.     <mvc:mapping path="/h*"/>
  43.     <mvc:exclude-mapping path="/hello"/>
  44.     <ref bean="myInterceptor02"/>
  45. </mvc:interceptor>throw new RuntimeException(e);<?xml version="1.0" encoding="UTF-8" ?>
  46. <beans>
  47.    
  48.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  49. </beans>}    }}
复制代码

  • 这个全部的路径 一个split(",")分隔,都进行扫描
  • 需要写自己的 前端控制器
  • 需要写自己的 Spring容器
  • 在前端控制器中 需要添加方法 scanPackage() 扫描 XMLParser 解析出来的路径
  1. public void scanPackage(String pack) {<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>//获得包地点的工作路径 [绝对路径]<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>URL url =<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor>    this.getClass().getClassLoader().//获取类的加载器<mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor><mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor>//得到指定包对应的工作路径 [绝对路径]    <bean >
  22.    
  23.    
  24. <?xml version="1.0" encoding="UTF-8" ?>
  25. <beans>
  26.    
  27.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  28. </beans><property name="prefix" value="/WEB-INF/pages/"/>
  29. <?xml version="1.0" encoding="UTF-8" ?>
  30. <beans>
  31.    
  32.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  33. </beans><property name="suffix" value=".jsp"/>
  34.     </bean>getResource("/" + pack.replaceAll("\\.", "/"));<?xml version="1.0" encoding="UTF-8" ?>
  35. <beans>
  36.    
  37.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  38. </beans>// System.out.println("url= "+url);<?xml version="1.0" encoding="UTF-8" ?>
  39. <beans>
  40.    
  41.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  42. </beans>//根据得到的路径,对其进行扫描,把类的全路径 保存到 classFullPathList<?xml version="1.0" encoding="UTF-8" ?>
  43. <beans>
  44.    
  45.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  46. </beans>String path = url.getFile();<?xml version="1.0" encoding="UTF-8" ?>
  47. <beans>
  48.    
  49.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  50. </beans>//在io中 把目录也是为一个文件<?xml version="1.0" encoding="UTF-8" ?>
  51. <beans>
  52.    
  53.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  54. </beans>File file = new File(path);<?xml version="1.0" encoding="UTF-8" ?>
  55. <beans>
  56.    
  57.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  58. </beans>//遍历file 【遍历出文件和子目录】<?xml version="1.0" encoding="UTF-8" ?>
  59. <beans>
  60.    
  61.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  62. </beans>for (File f : file.listFiles()) {<mvc:interceptor>
  63.     <mvc:mapping path="/h*"/>
  64.     <mvc:exclude-mapping path="/hello"/>
  65.     <ref bean="myInterceptor02"/>
  66. </mvc:interceptor>if (f.isDirectory()) {//如果是目录<mvc:interceptor>
  67.     <mvc:mapping path="/h*"/>
  68.     <mvc:exclude-mapping path="/hello"/>
  69.     <ref bean="myInterceptor02"/>
  70. </mvc:interceptor>    //需要递归扫描 找子目录<mvc:interceptor>
  71.     <mvc:mapping path="/h*"/>
  72.     <mvc:exclude-mapping path="/hello"/>
  73.     <ref bean="myInterceptor02"/>
  74. </mvc:interceptor>    scanPackage(pack + "." + f.getName());<mvc:interceptor>
  75.     <mvc:mapping path="/h*"/>
  76.     <mvc:exclude-mapping path="/hello"/>
  77.     <ref bean="myInterceptor02"/>
  78. </mvc:interceptor>} else {<mvc:interceptor>
  79.     <mvc:mapping path="/h*"/>
  80.     <mvc:exclude-mapping path="/hello"/>
  81.     <ref bean="myInterceptor02"/>
  82. </mvc:interceptor>    //的确是个文件<mvc:interceptor>
  83.     <mvc:mapping path="/h*"/>
  84.     <mvc:exclude-mapping path="/hello"/>
  85.     <ref bean="myInterceptor02"/>
  86. </mvc:interceptor>    //扫描到的文件可能是 .class 文件 也可能是其他文件<mvc:interceptor>
  87.     <mvc:mapping path="/h*"/>
  88.     <mvc:exclude-mapping path="/hello"/>
  89.     <ref bean="myInterceptor02"/>
  90. </mvc:interceptor>    //就算是.class 文件 也需要判断是否需要注入容器 有无加 @Controller注解<mvc:interceptor>
  91.     <mvc:mapping path="/h*"/>
  92.     <mvc:exclude-mapping path="/hello"/>
  93.     <ref bean="myInterceptor02"/>
  94. </mvc:interceptor>    //现在无法拿到注解 因为没法反射 所以先把文件的全路径都保存到 classFullPathList 之后在注入对象到容器时再处置处罚<mvc:interceptor>
  95.     <mvc:mapping path="/h*"/>
  96.     <mvc:exclude-mapping path="/hello"/>
  97.     <ref bean="myInterceptor02"/>
  98. </mvc:interceptor>    String classFullPath =<mvc:interceptor>
  99.     <mvc:mapping path="/h*"/>
  100.     <mvc:exclude-mapping path="/hello"/>
  101.     <ref bean="myInterceptor02"/>
  102. </mvc:interceptor><mvc:interceptor>
  103.     <mvc:mapping path="/h*"/>
  104.     <mvc:exclude-mapping path="/hello"/>
  105.     <ref bean="myInterceptor02"/>
  106. </mvc:interceptor>//类的全路径不需要.class 去掉.class<mvc:interceptor>
  107.     <mvc:mapping path="/h*"/>
  108.     <mvc:exclude-mapping path="/hello"/>
  109.     <ref bean="myInterceptor02"/>
  110. </mvc:interceptor><mvc:interceptor>
  111.     <mvc:mapping path="/h*"/>
  112.     <mvc:exclude-mapping path="/hello"/>
  113.     <ref bean="myInterceptor02"/>
  114. </mvc:interceptor>pack + "." + f.getName().replaceAll(".class", "");<mvc:interceptor>
  115.     <mvc:mapping path="/h*"/>
  116.     <mvc:exclude-mapping path="/hello"/>
  117.     <ref bean="myInterceptor02"/>
  118. </mvc:interceptor>    //保存到 classFullPathList<mvc:interceptor>
  119.     <mvc:mapping path="/h*"/>
  120.     <mvc:exclude-mapping path="/hello"/>
  121.     <ref bean="myInterceptor02"/>
  122. </mvc:interceptor>    classFullPathList.add(classFullPath);<mvc:interceptor>
  123.     <mvc:mapping path="/h*"/>
  124.     <mvc:exclude-mapping path="/hello"/>
  125.     <ref bean="myInterceptor02"/>
  126. </mvc:interceptor>}<?xml version="1.0" encoding="UTF-8" ?>
  127. <beans>
  128.    
  129.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  130. </beans>}    }
复制代码

  • 在Spring容器中 需要添加一个属性 classFullPathList 来保存扫描出来的类的全路径
  1. //保存扫描的包/子包类的全路径    private List classFullPathList =<mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor>new ArrayList();
复制代码

  • 需要添加一个属性 ioc 来存放反射生成的bean对象 也就是过滤classFullPathList  中没有@Controller注解的一些路径 并实例化
  1. //定义属性 ioc -> 存放反射生成的bean对象 比如Controller / Service /Daopublic ConcurrentHashMap ioc =<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>new ConcurrentHashMap();
复制代码

  • 编写方法,将扫描到的类,在满足情况下 反射到ioc容器
  1. //编写方法,将扫描到的类,在满足情况下 反射到ioc容器    public void executeInstance() {<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>if (classFullPathList.size() == 0) {<mvc:interceptor>
  6.     <mvc:mapping path="/h*"/>
  7.     <mvc:exclude-mapping path="/hello"/>
  8.     <ref bean="myInterceptor02"/>
  9. </mvc:interceptor>//分析没有扫描到类<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor>return;<?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>}<?xml version="1.0" encoding="UTF-8" ?>
  18. <beans>
  19.    
  20.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  21. </beans>//遍历classFullList<?xml version="1.0" encoding="UTF-8" ?>
  22. <beans>
  23.    
  24.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  25. </beans>for (String classFullPath : classFullPathList) {<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor>try {<mvc:interceptor>
  30.     <mvc:mapping path="/h*"/>
  31.     <mvc:exclude-mapping path="/hello"/>
  32.     <ref bean="myInterceptor02"/>
  33. </mvc:interceptor>    Class clazz = Class.forName(classFullPath);<mvc:interceptor>
  34.     <mvc:mapping path="/h*"/>
  35.     <mvc:exclude-mapping path="/hello"/>
  36.     <ref bean="myInterceptor02"/>
  37. </mvc:interceptor>    if (clazz.isAnnotationPresent(Controller.class)) {//处置处罚@Controller<mvc:interceptor>
  38.     <mvc:mapping path="/h*"/>
  39.     <mvc:exclude-mapping path="/hello"/>
  40.     <ref bean="myInterceptor02"/>
  41. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  42. <beans>
  43.    
  44.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  45. </beans>String className = clazz.getSimpleName();<mvc:interceptor>
  46.     <mvc:mapping path="/h*"/>
  47.     <mvc:exclude-mapping path="/hello"/>
  48.     <ref bean="myInterceptor02"/>
  49. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  50. <beans>
  51.    
  52.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  53. </beans>Object instance = clazz.newInstance();<mvc:interceptor>
  54.     <mvc:mapping path="/h*"/>
  55.     <mvc:exclude-mapping path="/hello"/>
  56.     <ref bean="myInterceptor02"/>
  57. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  58. <beans>
  59.    
  60.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  61. </beans>String value = clazz.getAnnotation(Controller.class).value();<mvc:interceptor>
  62.     <mvc:mapping path="/h*"/>
  63.     <mvc:exclude-mapping path="/hello"/>
  64.     <ref bean="myInterceptor02"/>
  65. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  66. <beans>
  67.    
  68.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  69. </beans>if (!"".equals(value)) {<mvc:interceptor>
  70.     <mvc:mapping path="/h*"/>
  71.     <mvc:exclude-mapping path="/hello"/>
  72.     <ref bean="myInterceptor02"/>
  73. </mvc:interceptor><mvc:interceptor>
  74.     <mvc:mapping path="/h*"/>
  75.     <mvc:exclude-mapping path="/hello"/>
  76.     <ref bean="myInterceptor02"/>
  77. </mvc:interceptor>className = value;<mvc:interceptor>
  78.     <mvc:mapping path="/h*"/>
  79.     <mvc:exclude-mapping path="/hello"/>
  80.     <ref bean="myInterceptor02"/>
  81. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  82. <beans>
  83.    
  84.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  85. </beans>} else {<mvc:interceptor>
  86.     <mvc:mapping path="/h*"/>
  87.     <mvc:exclude-mapping path="/hello"/>
  88.     <ref bean="myInterceptor02"/>
  89. </mvc:interceptor><mvc:interceptor>
  90.     <mvc:mapping path="/h*"/>
  91.     <mvc:exclude-mapping path="/hello"/>
  92.     <ref bean="myInterceptor02"/>
  93. </mvc:interceptor>className = StringUtils.uncapitalize(className);<mvc:interceptor>
  94.     <mvc:mapping path="/h*"/>
  95.     <mvc:exclude-mapping path="/hello"/>
  96.     <ref bean="myInterceptor02"/>
  97. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  98. <beans>
  99.    
  100.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  101. </beans>}<mvc:interceptor>
  102.     <mvc:mapping path="/h*"/>
  103.     <mvc:exclude-mapping path="/hello"/>
  104.     <ref bean="myInterceptor02"/>
  105. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  106. <beans>
  107.    
  108.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  109. </beans>ioc.put(className, instance);<mvc:interceptor>
  110.     <mvc:mapping path="/h*"/>
  111.     <mvc:exclude-mapping path="/hello"/>
  112.     <ref bean="myInterceptor02"/>
  113. </mvc:interceptor>    }<mvc:interceptor>
  114.     <mvc:mapping path="/h*"/>
  115.     <mvc:exclude-mapping path="/hello"/>
  116.     <ref bean="myInterceptor02"/>
  117. </mvc:interceptor>    else if (clazz.isAnnotationPresent(Service.class)) {//处置处罚@Service<mvc:interceptor>
  118.     <mvc:mapping path="/h*"/>
  119.     <mvc:exclude-mapping path="/hello"/>
  120.     <ref bean="myInterceptor02"/>
  121. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  122. <beans>
  123.    
  124.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  125. </beans>String className = clazz.getSimpleName();//类名<mvc:interceptor>
  126.     <mvc:mapping path="/h*"/>
  127.     <mvc:exclude-mapping path="/hello"/>
  128.     <ref bean="myInterceptor02"/>
  129. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  130. <beans>
  131.    
  132.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  133. </beans>Service serviceAnnotation = clazz.getAnnotation(Service.class);<mvc:interceptor>
  134.     <mvc:mapping path="/h*"/>
  135.     <mvc:exclude-mapping path="/hello"/>
  136.     <ref bean="myInterceptor02"/>
  137. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  138. <beans>
  139.    
  140.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  141. </beans>String value = serviceAnnotation.value();<mvc:interceptor>
  142.     <mvc:mapping path="/h*"/>
  143.     <mvc:exclude-mapping path="/hello"/>
  144.     <ref bean="myInterceptor02"/>
  145. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  146. <beans>
  147.    
  148.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  149. </beans>if (!"".equals(value)) {<mvc:interceptor>
  150.     <mvc:mapping path="/h*"/>
  151.     <mvc:exclude-mapping path="/hello"/>
  152.     <ref bean="myInterceptor02"/>
  153. </mvc:interceptor><mvc:interceptor>
  154.     <mvc:mapping path="/h*"/>
  155.     <mvc:exclude-mapping path="/hello"/>
  156.     <ref bean="myInterceptor02"/>
  157. </mvc:interceptor>className = value;<mvc:interceptor>
  158.     <mvc:mapping path="/h*"/>
  159.     <mvc:exclude-mapping path="/hello"/>
  160.     <ref bean="myInterceptor02"/>
  161. </mvc:interceptor><mvc:interceptor>
  162.     <mvc:mapping path="/h*"/>
  163.     <mvc:exclude-mapping path="/hello"/>
  164.     <ref bean="myInterceptor02"/>
  165. </mvc:interceptor>Object instance = clazz.newInstance();<mvc:interceptor>
  166.     <mvc:mapping path="/h*"/>
  167.     <mvc:exclude-mapping path="/hello"/>
  168.     <ref bean="myInterceptor02"/>
  169. </mvc:interceptor><mvc:interceptor>
  170.     <mvc:mapping path="/h*"/>
  171.     <mvc:exclude-mapping path="/hello"/>
  172.     <ref bean="myInterceptor02"/>
  173. </mvc:interceptor>ioc.put(className, instance);<bean >
  174.         <property name="order" value="99"></property>
  175. </bean><bean >
  176.         <property name="order" value="99"></property>
  177. </bean><bean >
  178.         <property name="order" value="99"></property>
  179. </bean><bean >
  180.         <property name="order" value="99"></property>
  181. </bean>}<mvc:interceptor>
  182.     <mvc:mapping path="/h*"/>
  183.     <mvc:exclude-mapping path="/hello"/>
  184.     <ref bean="myInterceptor02"/>
  185. </mvc:interceptor>} catch (Exception e) {<mvc:interceptor>
  186.     <mvc:mapping path="/h*"/>
  187.     <mvc:exclude-mapping path="/hello"/>
  188.     <ref bean="myInterceptor02"/>
  189. </mvc:interceptor>    throw new RuntimeException(e);<mvc:interceptor>
  190.     <mvc:mapping path="/h*"/>
  191.     <mvc:exclude-mapping path="/hello"/>
  192.     <ref bean="myInterceptor02"/>
  193. </mvc:interceptor>}<?xml version="1.0" encoding="UTF-8" ?>
  194. <beans>
  195.    
  196.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  197. </beans>}    }
复制代码

  • 需要添加类Handler 这个类要保存 一个url 对应的 一个控制器的方法的 映射 ,也就是说,根据这个url,可以找到对应控制器的对应方法
  1. ZyHandler {    private String url;    private Method method;    private Object controller;    public ZyHandler() {    }    public ZyHandler(String url, Method method, Object controller) {<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>this.url = url;<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>this.method = method;<?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>this.controller = controller;    }//需要提供getter和setter方法...
复制代码

  • 需要添加一个属性 HandlerList 用于 保存Handler 【url 和 控制器的映射】
  1. //定义属性 HandlerList -> 保存ZyHandler 【url 和 控制器的映射】    private List HandlerList =<mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor>new ArrayList();
复制代码

  • 需要添加三个方法 一个是initHandlerMapping(),完成 url 对应的 一个控制器的方法的 映射,即 将ioc 中bean 中的 方法进行反射,获取url,将 url,method,bean 封装成Handler  放入HandlerList  保存
  1. private void initHandlerMapping(){<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>//遍历 ioc<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>for (Map.Entry entry:  zyWebApplicationContext.ioc.entrySet()) {<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor>if (zyWebApplicationContext.ioc.isEmpty()){<mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor>    return;<mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor>}<mvc:interceptor>
  22.     <mvc:mapping path="/h*"/>
  23.     <mvc:exclude-mapping path="/hello"/>
  24.     <ref bean="myInterceptor02"/>
  25. </mvc:interceptor>Object bean = entry.getValue();<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor>Class clazz = bean.getClass();<mvc:interceptor>
  30.     <mvc:mapping path="/h*"/>
  31.     <mvc:exclude-mapping path="/hello"/>
  32.     <ref bean="myInterceptor02"/>
  33. </mvc:interceptor>if (clazz.isAnnotationPresent(Controller.class)){<mvc:interceptor>
  34.     <mvc:mapping path="/h*"/>
  35.     <mvc:exclude-mapping path="/hello"/>
  36.     <ref bean="myInterceptor02"/>
  37. </mvc:interceptor>    Method[] declaredMethods = clazz.getDeclaredMethods();<mvc:interceptor>
  38.     <mvc:mapping path="/h*"/>
  39.     <mvc:exclude-mapping path="/hello"/>
  40.     <ref bean="myInterceptor02"/>
  41. </mvc:interceptor>    for (Method declaredMethod : declaredMethods) {<mvc:interceptor>
  42.     <mvc:mapping path="/h*"/>
  43.     <mvc:exclude-mapping path="/hello"/>
  44.     <ref bean="myInterceptor02"/>
  45. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  46. <beans>
  47.    
  48.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  49. </beans>if (declaredMethod.isAnnotationPresent(RequestMapping.class)){<mvc:interceptor>
  50.     <mvc:mapping path="/h*"/>
  51.     <mvc:exclude-mapping path="/hello"/>
  52.     <ref bean="myInterceptor02"/>
  53. </mvc:interceptor><mvc:interceptor>
  54.     <mvc:mapping path="/h*"/>
  55.     <mvc:exclude-mapping path="/hello"/>
  56.     <ref bean="myInterceptor02"/>
  57. </mvc:interceptor>String url = declaredMethod.getAnnotation(RequestMapping.class).value();<mvc:interceptor>
  58.     <mvc:mapping path="/h*"/>
  59.     <mvc:exclude-mapping path="/hello"/>
  60.     <ref bean="myInterceptor02"/>
  61. </mvc:interceptor><mvc:interceptor>
  62.     <mvc:mapping path="/h*"/>
  63.     <mvc:exclude-mapping path="/hello"/>
  64.     <ref bean="myInterceptor02"/>
  65. </mvc:interceptor>ZyHandler zyHandler = new ZyHandler(url, declaredMethod, bean);<mvc:interceptor>
  66.     <mvc:mapping path="/h*"/>
  67.     <mvc:exclude-mapping path="/hello"/>
  68.     <ref bean="myInterceptor02"/>
  69. </mvc:interceptor><mvc:interceptor>
  70.     <mvc:mapping path="/h*"/>
  71.     <mvc:exclude-mapping path="/hello"/>
  72.     <ref bean="myInterceptor02"/>
  73. </mvc:interceptor>HandlerList.add(zyHandler);<mvc:interceptor>
  74.     <mvc:mapping path="/h*"/>
  75.     <mvc:exclude-mapping path="/hello"/>
  76.     <ref bean="myInterceptor02"/>
  77. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  78. <beans>
  79.    
  80.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  81. </beans>}<mvc:interceptor>
  82.     <mvc:mapping path="/h*"/>
  83.     <mvc:exclude-mapping path="/hello"/>
  84.     <ref bean="myInterceptor02"/>
  85. </mvc:interceptor>    }<mvc:interceptor>
  86.     <mvc:mapping path="/h*"/>
  87.     <mvc:exclude-mapping path="/hello"/>
  88.     <ref bean="myInterceptor02"/>
  89. </mvc:interceptor>}<?xml version="1.0" encoding="UTF-8" ?>
  90. <beans>
  91.    
  92.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  93. </beans>}    }
复制代码

  • 添加第二个方法 getHandler(),需要将浏览器发送的request请求中的 uri拿出来,遍历HandlerList  进行配对,如果有 就返回对应的Handler
  1. //编写方法,通过request对象 返回ZyHandler对象 ,如果没有返回null    private ZyHandler getZyHandler(HttpServletRequest request) {<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>String requestURI = request.getRequestURI();<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>//遍历HandlerList<?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>for (ZyHandler zyHandler : HandlerList) {<mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor>if (requestURI.equals(zyHandler.getUrl())){<mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor>    return zyHandler;<mvc:interceptor>
  22.     <mvc:mapping path="/h*"/>
  23.     <mvc:exclude-mapping path="/hello"/>
  24.     <ref bean="myInterceptor02"/>
  25. </mvc:interceptor>}<?xml version="1.0" encoding="UTF-8" ?>
  26. <beans>
  27.    
  28.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  29. </beans>}<?xml version="1.0" encoding="UTF-8" ?>
  30. <beans>
  31.    
  32.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  33. </beans>return null;    }
复制代码

  • 添加第三个方法 executeDispatch(),进行分发处置处罚,需要 调用getHandler() 获取浏览器发送的request请求 对应的 Handler  ,获取Handler  中的method 进行反射调用,method .invoke() 实现分发请求。
  1.    public void executeDispatch(HttpServletRequest request,HttpServletResponse response){<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>ZyHandler zyHandler = getZyHandler(request);<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>try {<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor>if (null == zyHandler){<mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor>   response.getWriter().write("[size=6]404 NOT FOUND[/size]
  18. ");<mvc:interceptor>
  19.     <mvc:mapping path="/h*"/>
  20.     <mvc:exclude-mapping path="/hello"/>
  21.     <ref bean="myInterceptor02"/>
  22. </mvc:interceptor>}<mvc:interceptor>
  23.     <mvc:mapping path="/h*"/>
  24.     <mvc:exclude-mapping path="/hello"/>
  25.     <ref bean="myInterceptor02"/>
  26. </mvc:interceptor>Method method = zyHandler.getMethod();<mvc:interceptor>
  27.     <mvc:mapping path="/h*"/>
  28.     <mvc:exclude-mapping path="/hello"/>
  29.     <ref bean="myInterceptor02"/>
  30. </mvc:interceptor>method.invoke(zyHandler.getController(),request,response);<?xml version="1.0" encoding="UTF-8" ?>
  31. <beans>
  32.    
  33.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  34. </beans>} catch (Exception e) {<mvc:interceptor>
  35.     <mvc:mapping path="/h*"/>
  36.     <mvc:exclude-mapping path="/hello"/>
  37.     <ref bean="myInterceptor02"/>
  38. </mvc:interceptor>throw new RuntimeException(e);<?xml version="1.0" encoding="UTF-8" ?>
  39. <beans>
  40.    
  41.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  42. </beans>}    }
复制代码
从web.xml文件中动态获取spring配置文件

思路


  • 首先,我们自己写的前端控制器是一个Servlet,它有 servletConfig,可以servletConfig.getInitParameter("xxx") 来获取之前在web.xml配置的classpath:
  • 工具类XMLParser 是在spring容器中解析的 ,web.xml配置的classpath: 是在前端控制器中获取的,因此需要spring容器提供有参构造器,在前端控制器添加参数 spring容器,将classpath 传到spring容器中进行解析。
实现


  • 首先,我们自己写的前端控制器是一个Servlet,它有 servletConfig,可以servletConfig.getInitParameter("xxx") 来获取之前在web.xml配置的classpath:
  • 工具类XMLParser 是在spring容器中解析的 ,web.xml配置的classpath: 是在前端控制器中获取的,因此需要spring容器提供有参构造器,在前端控制器添加参数 spring容器,将classpath 传到spring容器中进行解析。
  1. @Override    public void init() throws ServletException {<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>String configLocation = getServletConfig().getInitParameter("contextConfigLocation");<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>System.out.println("ZyDispatcherServlet 初始化---");<?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>zyWebApplicationContext = new ZyWebApplicationContext(configLocation);<?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>zyWebApplicationContext.init();<?xml version="1.0" encoding="UTF-8" ?>
  18. <beans>
  19.    
  20.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  21. </beans>initHandlerMapping();<?xml version="1.0" encoding="UTF-8" ?>
  22. <beans>
  23.    
  24.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  25. </beans>System.out.println("HandlerList= "+HandlerList);    }
复制代码
  1. private  String configLocation;    public ZyWebApplicationContext(String configLocation) {<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>this.configLocation = configLocation;    }
复制代码
  1. public void init(){<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>System.out.println("ZyWebApplicationContext 初始化---");<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>String basePackage = XMLParser.getBasePackage(configLocation.split(":")[1]);<?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>String[] basePackages = basePackage.split(",");<?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>if (basePackages.length >0) {<mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor>for (String  pack : basePackages) {<mvc:interceptor>
  22.     <mvc:mapping path="/h*"/>
  23.     <mvc:exclude-mapping path="/hello"/>
  24.     <ref bean="myInterceptor02"/>
  25. </mvc:interceptor>    scanPackage(pack);<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor>}<?xml version="1.0" encoding="UTF-8" ?>
  30. <beans>
  31.    
  32.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  33. </beans>} }
复制代码
@Service注解

思路


  • @Service注解是写在类上的 即@Target(ElementType.TYPE)
  • 这个注解标识的类就是一个Service,那么同样是在executeInstance()方法中判断是否有注解@Service,有的话就保存到ioc容器中
  • 由于是Service,那么保存进ioc 的 k-v 中的 k 就有三种。第一种,就是默认值,用接口的类型的名字首字母小写;第二种,在@Service注解种设置了value属性,那么 k = value;第三章,需要用类名首字母小写也可以获取bean
实现


  • @Service注解是写在类上的 即@Target(ElementType.TYPE)
  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface Service {
  5.     String value() default "";
  6. }
复制代码

  • 这个注解标识的类就是一个Service,那么同样是在executeInstance()方法中判断是否有注解@Service,有的话就保存到ioc容器中
  • 由于是Service,那么保存进ioc 的 k-v 中的 k 就有三种。第一种,就是默认值,用接口的类型的名字首字母小写;第二种,在@Service注解种设置了value属性,那么 k = value;第三章,需要用类名首字母小写也可以获取bean
  1. public void executeInstance() {<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>if (classFullPathList.size() == 0){<mvc:interceptor>
  6.     <mvc:mapping path="/h*"/>
  7.     <mvc:exclude-mapping path="/hello"/>
  8.     <ref bean="myInterceptor02"/>
  9. </mvc:interceptor>return;<?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>}<?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>//遍历 classFullPathList<?xml version="1.0" encoding="UTF-8" ?>
  18. <beans>
  19.    
  20.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  21. </beans>for (String classFullPath : classFullPathList) {<mvc:interceptor>
  22.     <mvc:mapping path="/h*"/>
  23.     <mvc:exclude-mapping path="/hello"/>
  24.     <ref bean="myInterceptor02"/>
  25. </mvc:interceptor>try {<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor>    Class clazz = Class.forName(classFullPath);<mvc:interceptor>
  30.     <mvc:mapping path="/h*"/>
  31.     <mvc:exclude-mapping path="/hello"/>
  32.     <ref bean="myInterceptor02"/>
  33. </mvc:interceptor>    if (clazz.isAnnotationPresent(Controller.class)){<mvc:interceptor>
  34.     <mvc:mapping path="/h*"/>
  35.     <mvc:exclude-mapping path="/hello"/>
  36.     <ref bean="myInterceptor02"/>
  37. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  38. <beans>
  39.    
  40.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  41. </beans>Controller controller = clazz.getAnnotation(Controller.class);<mvc:interceptor>
  42.     <mvc:mapping path="/h*"/>
  43.     <mvc:exclude-mapping path="/hello"/>
  44.     <ref bean="myInterceptor02"/>
  45. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  46. <beans>
  47.    
  48.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  49. </beans>String value = controller.value();<mvc:interceptor>
  50.     <mvc:mapping path="/h*"/>
  51.     <mvc:exclude-mapping path="/hello"/>
  52.     <ref bean="myInterceptor02"/>
  53. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  54. <beans>
  55.    
  56.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  57. </beans>String className = clazz.getSimpleName();<mvc:interceptor>
  58.     <mvc:mapping path="/h*"/>
  59.     <mvc:exclude-mapping path="/hello"/>
  60.     <ref bean="myInterceptor02"/>
  61. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  62. <beans>
  63.    
  64.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  65. </beans>Object instance = clazz.newInstance();<mvc:interceptor>
  66.     <mvc:mapping path="/h*"/>
  67.     <mvc:exclude-mapping path="/hello"/>
  68.     <ref bean="myInterceptor02"/>
  69. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  70. <beans>
  71.    
  72.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  73. </beans>if ("".equals(value)){<mvc:interceptor>
  74.     <mvc:mapping path="/h*"/>
  75.     <mvc:exclude-mapping path="/hello"/>
  76.     <ref bean="myInterceptor02"/>
  77. </mvc:interceptor><mvc:interceptor>
  78.     <mvc:mapping path="/h*"/>
  79.     <mvc:exclude-mapping path="/hello"/>
  80.     <ref bean="myInterceptor02"/>
  81. </mvc:interceptor>className = StringUtils.uncapitalize(className);<mvc:interceptor>
  82.     <mvc:mapping path="/h*"/>
  83.     <mvc:exclude-mapping path="/hello"/>
  84.     <ref bean="myInterceptor02"/>
  85. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  86. <beans>
  87.    
  88.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  89. </beans>}else {<mvc:interceptor>
  90.     <mvc:mapping path="/h*"/>
  91.     <mvc:exclude-mapping path="/hello"/>
  92.     <ref bean="myInterceptor02"/>
  93. </mvc:interceptor><mvc:interceptor>
  94.     <mvc:mapping path="/h*"/>
  95.     <mvc:exclude-mapping path="/hello"/>
  96.     <ref bean="myInterceptor02"/>
  97. </mvc:interceptor>className = value;<mvc:interceptor>
  98.     <mvc:mapping path="/h*"/>
  99.     <mvc:exclude-mapping path="/hello"/>
  100.     <ref bean="myInterceptor02"/>
  101. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  102. <beans>
  103.    
  104.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  105. </beans>}<mvc:interceptor>
  106.     <mvc:mapping path="/h*"/>
  107.     <mvc:exclude-mapping path="/hello"/>
  108.     <ref bean="myInterceptor02"/>
  109. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  110. <beans>
  111.    
  112.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  113. </beans>ioc.put(className,instance);<mvc:interceptor>
  114.     <mvc:mapping path="/h*"/>
  115.     <mvc:exclude-mapping path="/hello"/>
  116.     <ref bean="myInterceptor02"/>
  117. </mvc:interceptor>    } else if (clazz.isAnnotationPresent(Service.class)) {<mvc:interceptor>
  118.     <mvc:mapping path="/h*"/>
  119.     <mvc:exclude-mapping path="/hello"/>
  120.     <ref bean="myInterceptor02"/>
  121. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  122. <beans>
  123.    
  124.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  125. </beans>Service serviceAnnotation = clazz.getAnnotation(Service.class);<mvc:interceptor>
  126.     <mvc:mapping path="/h*"/>
  127.     <mvc:exclude-mapping path="/hello"/>
  128.     <ref bean="myInterceptor02"/>
  129. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  130. <beans>
  131.    
  132.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  133. </beans>String annoattionValue = serviceAnnotation.value();<mvc:interceptor>
  134.     <mvc:mapping path="/h*"/>
  135.     <mvc:exclude-mapping path="/hello"/>
  136.     <ref bean="myInterceptor02"/>
  137. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  138. <beans>
  139.    
  140.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  141. </beans>Object instance = clazz.newInstance();<mvc:interceptor>
  142.     <mvc:mapping path="/h*"/>
  143.     <mvc:exclude-mapping path="/hello"/>
  144.     <ref bean="myInterceptor02"/>
  145. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  146. <beans>
  147.    
  148.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  149. </beans>if ("".equals(annoattionValue)){<mvc:interceptor>
  150.     <mvc:mapping path="/h*"/>
  151.     <mvc:exclude-mapping path="/hello"/>
  152.     <ref bean="myInterceptor02"/>
  153. </mvc:interceptor><mvc:interceptor>
  154.     <mvc:mapping path="/h*"/>
  155.     <mvc:exclude-mapping path="/hello"/>
  156.     <ref bean="myInterceptor02"/>
  157. </mvc:interceptor>Class[] interfaces = clazz.getInterfaces();<mvc:interceptor>
  158.     <mvc:mapping path="/h*"/>
  159.     <mvc:exclude-mapping path="/hello"/>
  160.     <ref bean="myInterceptor02"/>
  161. </mvc:interceptor><mvc:interceptor>
  162.     <mvc:mapping path="/h*"/>
  163.     <mvc:exclude-mapping path="/hello"/>
  164.     <ref bean="myInterceptor02"/>
  165. </mvc:interceptor>for (Class anInterface : interfaces) {
  166.     <bean id="messageSource" class=
  167. <mvc:interceptor>
  168.     <mvc:mapping path="/h*"/>
  169.     <mvc:exclude-mapping path="/hello"/>
  170.     <ref bean="myInterceptor02"/>
  171. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  172. <?xml version="1.0" encoding="UTF-8" ?>
  173. <beans>
  174.    
  175.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  176. </beans>
  177. <?xml version="1.0" encoding="UTF-8" ?>
  178. <beans>
  179.    
  180.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  181. </beans><property name="basename" value="i18n"></property>
  182.     </bean>   String simpleName = anInterface.getSimpleName();
  183.     <bean id="messageSource" class=
  184. <mvc:interceptor>
  185.     <mvc:mapping path="/h*"/>
  186.     <mvc:exclude-mapping path="/hello"/>
  187.     <ref bean="myInterceptor02"/>
  188. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  189. <?xml version="1.0" encoding="UTF-8" ?>
  190. <beans>
  191.    
  192.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  193. </beans>
  194. <?xml version="1.0" encoding="UTF-8" ?>
  195. <beans>
  196.    
  197.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  198. </beans><property name="basename" value="i18n"></property>
  199.     </bean>   simpleName = StringUtils.uncapitalize(simpleName);
  200.     <bean id="messageSource" class=
  201. <mvc:interceptor>
  202.     <mvc:mapping path="/h*"/>
  203.     <mvc:exclude-mapping path="/hello"/>
  204.     <ref bean="myInterceptor02"/>
  205. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  206. <?xml version="1.0" encoding="UTF-8" ?>
  207. <beans>
  208.    
  209.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  210. </beans>
  211. <?xml version="1.0" encoding="UTF-8" ?>
  212. <beans>
  213.    
  214.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  215. </beans><property name="basename" value="i18n"></property>
  216.     </bean>   ioc.put(simpleName,instance);<mvc:interceptor>
  217.     <mvc:mapping path="/h*"/>
  218.     <mvc:exclude-mapping path="/hello"/>
  219.     <ref bean="myInterceptor02"/>
  220. </mvc:interceptor><mvc:interceptor>
  221.     <mvc:mapping path="/h*"/>
  222.     <mvc:exclude-mapping path="/hello"/>
  223.     <ref bean="myInterceptor02"/>
  224. </mvc:interceptor>}<mvc:interceptor>
  225.     <mvc:mapping path="/h*"/>
  226.     <mvc:exclude-mapping path="/hello"/>
  227.     <ref bean="myInterceptor02"/>
  228. </mvc:interceptor><mvc:interceptor>
  229.     <mvc:mapping path="/h*"/>
  230.     <mvc:exclude-mapping path="/hello"/>
  231.     <ref bean="myInterceptor02"/>
  232. </mvc:interceptor>//可以通过类名首字母小写<mvc:interceptor>
  233.     <mvc:mapping path="/h*"/>
  234.     <mvc:exclude-mapping path="/hello"/>
  235.     <ref bean="myInterceptor02"/>
  236. </mvc:interceptor><mvc:interceptor>
  237.     <mvc:mapping path="/h*"/>
  238.     <mvc:exclude-mapping path="/hello"/>
  239.     <ref bean="myInterceptor02"/>
  240. </mvc:interceptor>String simpleName = clazz.getSimpleName();<mvc:interceptor>
  241.     <mvc:mapping path="/h*"/>
  242.     <mvc:exclude-mapping path="/hello"/>
  243.     <ref bean="myInterceptor02"/>
  244. </mvc:interceptor><mvc:interceptor>
  245.     <mvc:mapping path="/h*"/>
  246.     <mvc:exclude-mapping path="/hello"/>
  247.     <ref bean="myInterceptor02"/>
  248. </mvc:interceptor>simpleName = StringUtils.uncapitalize(simpleName);<mvc:interceptor>
  249.     <mvc:mapping path="/h*"/>
  250.     <mvc:exclude-mapping path="/hello"/>
  251.     <ref bean="myInterceptor02"/>
  252. </mvc:interceptor><mvc:interceptor>
  253.     <mvc:mapping path="/h*"/>
  254.     <mvc:exclude-mapping path="/hello"/>
  255.     <ref bean="myInterceptor02"/>
  256. </mvc:interceptor>ioc.put(simpleName,instance);<mvc:interceptor>
  257.     <mvc:mapping path="/h*"/>
  258.     <mvc:exclude-mapping path="/hello"/>
  259.     <ref bean="myInterceptor02"/>
  260. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  261. <beans>
  262.    
  263.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  264. </beans>}else {<mvc:interceptor>
  265.     <mvc:mapping path="/h*"/>
  266.     <mvc:exclude-mapping path="/hello"/>
  267.     <ref bean="myInterceptor02"/>
  268. </mvc:interceptor><mvc:interceptor>
  269.     <mvc:mapping path="/h*"/>
  270.     <mvc:exclude-mapping path="/hello"/>
  271.     <ref bean="myInterceptor02"/>
  272. </mvc:interceptor>ioc.put(annoattionValue,instance);<mvc:interceptor>
  273.     <mvc:mapping path="/h*"/>
  274.     <mvc:exclude-mapping path="/hello"/>
  275.     <ref bean="myInterceptor02"/>
  276. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  277. <beans>
  278.    
  279.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  280. </beans>}<mvc:interceptor>
  281.     <mvc:mapping path="/h*"/>
  282.     <mvc:exclude-mapping path="/hello"/>
  283.     <ref bean="myInterceptor02"/>
  284. </mvc:interceptor>    }<mvc:interceptor>
  285.     <mvc:mapping path="/h*"/>
  286.     <mvc:exclude-mapping path="/hello"/>
  287.     <ref bean="myInterceptor02"/>
  288. </mvc:interceptor>} catch (Exception e) {<mvc:interceptor>
  289.     <mvc:mapping path="/h*"/>
  290.     <mvc:exclude-mapping path="/hello"/>
  291.     <ref bean="myInterceptor02"/>
  292. </mvc:interceptor>    throw new RuntimeException(e);<mvc:interceptor>
  293.     <mvc:mapping path="/h*"/>
  294.     <mvc:exclude-mapping path="/hello"/>
  295.     <ref bean="myInterceptor02"/>
  296. </mvc:interceptor>}<?xml version="1.0" encoding="UTF-8" ?>
  297. <beans>
  298.    
  299.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  300. </beans>}    }
复制代码
@Autowried 依靠注入

思路


  • @Autowried注解是用在字段上,通过ioc容器自动装配,因此 @Target(ElementType.FIELD)
  • 需要遍历ioc中全部的 bean 中的全部字段,来进行判断是否需要自动装配
  • 通过反射获取字段,判断该字段是否带有@Autowried 注解,有的话就判断value值
  • value为"",分析按默认规则 用字段类型首字母小写 去ioc容器进行查找,如果没有抛出空指针异常throw new NullPointerException("ioc 没有该bean");
  • 如果有值,去ioc容器进行查找该值对应的bean,如果没有抛出空指针异常throw new NullPointerException("ioc 没有该bean");如果有该bean,就用该字段的set()方法将本身的bean 和 查找ioc获取的bean进行装配
  • 即 declaredField.set(bean, beanInIOC);
  • 由于字段是私有属性private,需要暴力破解declaredField.setAccessible(true);
实现


  • @Autowried注解是用在字段上,通过ioc容器自动装配,因此 @Target(ElementType.FIELD)
  1. @Target(ElementType.FIELD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface Autowired {
  5.     String value() default "";
  6. }
复制代码

  • 需要遍历ioc中全部的 bean 中的全部字段,来进行判断是否需要自动装配
  • 通过反射获取字段,判断该字段是否带有@Autowried 注解,有的话就判断value值
  • value为"",分析按默认规则 用字段类型首字母小写 去ioc容器进行查找,如果没有抛出空指针异常throw new NullPointerException("ioc 没有该bean");
  • 如果有值,去ioc容器进行查找该值对应的bean,如果没有抛出空指针异常throw new NullPointerException("ioc 没有该bean");如果有该bean,就用该字段的set()方法将本身的bean 和 查找ioc获取的bean进行装配
  • 即 declaredField.set(bean, beanInIOC);
  • 由于字段是私有属性private,需要暴力破解declaredField.setAccessible(true);
  1. public void  executeAutoWired(){    //遍历ioc    if (ioc.isEmpty()){<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>return;    }    //获取容器里的全部bean 以及 bean对应的字段    for (Map.Entry entry : ioc.entrySet()) {<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>Object bean = entry.getValue();<?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>Class clazz = bean.getClass();<?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>Field[] declaredFields = clazz.getDeclaredFields();<?xml version="1.0" encoding="UTF-8" ?>
  18. <beans>
  19.    
  20.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  21. </beans>for (Field declaredField : declaredFields) {<mvc:interceptor>
  22.     <mvc:mapping path="/h*"/>
  23.     <mvc:exclude-mapping path="/hello"/>
  24.     <ref bean="myInterceptor02"/>
  25. </mvc:interceptor>//通过反射获取字段,判断该字段是否带有@Autowried 注解,有的话就判断value值<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor>if (declaredField.isAnnotationPresent(Autowired.class)){<mvc:interceptor>
  30.     <mvc:mapping path="/h*"/>
  31.     <mvc:exclude-mapping path="/hello"/>
  32.     <ref bean="myInterceptor02"/>
  33. </mvc:interceptor>    Autowired annotation =<mvc:interceptor>
  34.     <mvc:mapping path="/h*"/>
  35.     <mvc:exclude-mapping path="/hello"/>
  36.     <ref bean="myInterceptor02"/>
  37. </mvc:interceptor><mvc:interceptor>
  38.     <mvc:mapping path="/h*"/>
  39.     <mvc:exclude-mapping path="/hello"/>
  40.     <ref bean="myInterceptor02"/>
  41. </mvc:interceptor>declaredField.getAnnotation(Autowired.class);<mvc:interceptor>
  42.     <mvc:mapping path="/h*"/>
  43.     <mvc:exclude-mapping path="/hello"/>
  44.     <ref bean="myInterceptor02"/>
  45. </mvc:interceptor>    String beanName = annotation.value();<mvc:interceptor>
  46.     <mvc:mapping path="/h*"/>
  47.     <mvc:exclude-mapping path="/hello"/>
  48.     <ref bean="myInterceptor02"/>
  49. </mvc:interceptor>    try {<mvc:interceptor>
  50.     <mvc:mapping path="/h*"/>
  51.     <mvc:exclude-mapping path="/hello"/>
  52.     <ref bean="myInterceptor02"/>
  53. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  54. <beans>
  55.    
  56.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  57. </beans>//value为"",分析按默认规则 用字段类型首字母小写 去ioc容器进行查找,<mvc:interceptor>
  58.     <mvc:mapping path="/h*"/>
  59.     <mvc:exclude-mapping path="/hello"/>
  60.     <ref bean="myInterceptor02"/>
  61. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  62. <beans>
  63.    
  64.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  65. </beans>if ("".equals(beanName)){<mvc:interceptor>
  66.     <mvc:mapping path="/h*"/>
  67.     <mvc:exclude-mapping path="/hello"/>
  68.     <ref bean="myInterceptor02"/>
  69. </mvc:interceptor><mvc:interceptor>
  70.     <mvc:mapping path="/h*"/>
  71.     <mvc:exclude-mapping path="/hello"/>
  72.     <ref bean="myInterceptor02"/>
  73. </mvc:interceptor>beanName = declaredField.getType().getSimpleName();<mvc:interceptor>
  74.     <mvc:mapping path="/h*"/>
  75.     <mvc:exclude-mapping path="/hello"/>
  76.     <ref bean="myInterceptor02"/>
  77. </mvc:interceptor><mvc:interceptor>
  78.     <mvc:mapping path="/h*"/>
  79.     <mvc:exclude-mapping path="/hello"/>
  80.     <ref bean="myInterceptor02"/>
  81. </mvc:interceptor>beanName = StringUtils.uncapitalize(beanName);<mvc:interceptor>
  82.     <mvc:mapping path="/h*"/>
  83.     <mvc:exclude-mapping path="/hello"/>
  84.     <ref bean="myInterceptor02"/>
  85. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  86. <beans>
  87.    
  88.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  89. </beans>}<mvc:interceptor>
  90.     <mvc:mapping path="/h*"/>
  91.     <mvc:exclude-mapping path="/hello"/>
  92.     <ref bean="myInterceptor02"/>
  93. </mvc:interceptor><mvc:interceptor>
  94.     <mvc:mapping path="/h*"/>
  95.     <mvc:exclude-mapping path="/hello"/>
  96.     <ref bean="myInterceptor02"/>
  97. </mvc:interceptor>Object iocBean = ioc.get(beanName);<mvc:interceptor>
  98.     <mvc:mapping path="/h*"/>
  99.     <mvc:exclude-mapping path="/hello"/>
  100.     <ref bean="myInterceptor02"/>
  101. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  102. <beans>
  103.    
  104.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  105. </beans>//如果没有抛出空指针异常<mvc:interceptor>
  106.     <mvc:mapping path="/h*"/>
  107.     <mvc:exclude-mapping path="/hello"/>
  108.     <ref bean="myInterceptor02"/>
  109. </mvc:interceptor><mvc:interceptor>
  110.     <mvc:mapping path="/h*"/>
  111.     <mvc:exclude-mapping path="/hello"/>
  112.     <ref bean="myInterceptor02"/>
  113. </mvc:interceptor>if (null == iocBean){
  114.     <bean id="messageSource" class=
  115. <mvc:interceptor>
  116.     <mvc:mapping path="/h*"/>
  117.     <mvc:exclude-mapping path="/hello"/>
  118.     <ref bean="myInterceptor02"/>
  119. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  120. <?xml version="1.0" encoding="UTF-8" ?>
  121. <beans>
  122.    
  123.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  124. </beans>
  125. <?xml version="1.0" encoding="UTF-8" ?>
  126. <beans>
  127.    
  128.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  129. </beans><property name="basename" value="i18n"></property>
  130.     </bean>   throw new NullPointerException("ioc 没有该Bean");<mvc:interceptor>
  131.     <mvc:mapping path="/h*"/>
  132.     <mvc:exclude-mapping path="/hello"/>
  133.     <ref bean="myInterceptor02"/>
  134. </mvc:interceptor><mvc:interceptor>
  135.     <mvc:mapping path="/h*"/>
  136.     <mvc:exclude-mapping path="/hello"/>
  137.     <ref bean="myInterceptor02"/>
  138. </mvc:interceptor>}<mvc:interceptor>
  139.     <mvc:mapping path="/h*"/>
  140.     <mvc:exclude-mapping path="/hello"/>
  141.     <ref bean="myInterceptor02"/>
  142. </mvc:interceptor><mvc:interceptor>
  143.     <mvc:mapping path="/h*"/>
  144.     <mvc:exclude-mapping path="/hello"/>
  145.     <ref bean="myInterceptor02"/>
  146. </mvc:interceptor>declaredField.setAccessible(true);//暴力破解<mvc:interceptor>
  147.     <mvc:mapping path="/h*"/>
  148.     <mvc:exclude-mapping path="/hello"/>
  149.     <ref bean="myInterceptor02"/>
  150. </mvc:interceptor><mvc:interceptor>
  151.     <mvc:mapping path="/h*"/>
  152.     <mvc:exclude-mapping path="/hello"/>
  153.     <ref bean="myInterceptor02"/>
  154. </mvc:interceptor>declaredField.set(bean,iocBean);<mvc:interceptor>
  155.     <mvc:mapping path="/h*"/>
  156.     <mvc:exclude-mapping path="/hello"/>
  157.     <ref bean="myInterceptor02"/>
  158. </mvc:interceptor>    } catch (IllegalAccessException e) {<mvc:interceptor>
  159.     <mvc:mapping path="/h*"/>
  160.     <mvc:exclude-mapping path="/hello"/>
  161.     <ref bean="myInterceptor02"/>
  162. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  163. <beans>
  164.    
  165.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  166. </beans>throw new RuntimeException(e);<mvc:interceptor>
  167.     <mvc:mapping path="/h*"/>
  168.     <mvc:exclude-mapping path="/hello"/>
  169.     <ref bean="myInterceptor02"/>
  170. </mvc:interceptor>    }<mvc:interceptor>
  171.     <mvc:mapping path="/h*"/>
  172.     <mvc:exclude-mapping path="/hello"/>
  173.     <ref bean="myInterceptor02"/>
  174. </mvc:interceptor>}<?xml version="1.0" encoding="UTF-8" ?>
  175. <beans>
  176.    
  177.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  178. </beans>}    }}
复制代码
@RequestParam

思路


  • @RequestParam 是写在PARAMETER上的 也就是说 @Target(ElementType.PARAMETER)
  • 这个注解实现的功能 大方向是 分发请求 也就是说 写在 executeDispatch()方法中的
  • 要实现 @RequestParam 需要将形参列表封装到一个数组中 , 因为反射 invoke 可以传入一个数组作为可变参数解析
  • 那么就需要两个数组 一个数组是新创建的数组(大小应与,目的数组的形参个数一致) 将实参放入进去 ;另一个是 反射拿到的目的方法的形参的数组
  • 这两个数组的内容需要一一对应,因为反射需要序次一致
  • 需要获取到request 中请求的参数Map 获取参数名和参数值
  • 可以将功能具体化到 完成这个新数组的实参填写 【完成新数组之后放入invoke方法进行反射就行】
  • 将步调拆解成 1)完成HttpServletRequest 和 HttpServletResponse 的填写 ;2)完成带有@RequestParam注解的形参的填写;3)完成普通的方法参数没有@RequestParam注解的形参的填写
  • 完成HttpServletRequest 和 HttpServletResponse 的填写:就需要先拿到目的方法的全部参数。根据类型的名称 和 形参列表进行匹配 填写
  • 完成带有@RequestParam注解的形参的填写:需要添加方法,获取目的方法中 带有@RequestParam注解的形参是属于第几个参数的,返回int 代表第几个参数,如果有@RequestParam注解,就会返回相应的索引,如果没有就会返回-1 进行普通方法参数的填写 处置处罚
  • 普通方法参数的 填写:需要添加方法,将目的方法的全部的形参的名称 反射保存到 List 返回,再通过遍历判断 请求的参数名  和 List中一致的 填写到 数组中
  • 普通方法参数的 填写 需要插件,使用java8的特性 解决在默认情况下 parameter.getName() 获取的名字不是形参真正的名字,而是[arg0,arg1,arg2...]的问题
实现


  • @RequestParam 是写在PARAMETER上的 也就是说 @Target(ElementType.PARAMETER)
  1. @Target(ElementType.PARAMETER)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface RequestParam {
  5.     String value() default "";
  6. }
复制代码

  • 这个注解实现的功能 大方向是 分发请求 也就是说 写在 executeDispatch()方法中的
  • 要实现 @RequestParam 需要将形参列表封装到一个数组中 , 因为反射 invoke 可以传入一个数组作为可变参数解析
  1. Method method = zyHandler.getMethod();
  2. Class<?>[] parameterTypes = method.getParameterTypes();//形参数组
  3. Object[] params = new Object[parameterTypes.length];
复制代码

  • 那么就需要两个数组 一个数组是新创建的数组(大小应与,目的数组的形参个数一致) 将实参放入进去 ;另一个是 反射拿到的目的方法的形参的数组
  • 这两个数组的内容需要一一对应,因为反射需要序次一致
  • 需要获取到request 中请求的参数Map 获取参数名和参数值
  1. request.setCharacterEncoding("utf-8");
  2. Map<String, String[]> parameterMap = request.getParameterMap();
  3. for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
  4.     String name = entry.getKey();//参数 键
  5.     String value = entry.getValue()[0];//参数 值
复制代码

  • 可以将功能具体化到 完成这个新数组的实参填写 【完成新数组之后放入invoke方法进行反射就行】
  • 将步调拆解成 1)完成HttpServletRequest 和 HttpServletResponse 的填写 ;2)完成带有@RequestParam注解的形参的填写;3)完成普通的方法参数没有@RequestParam注解的形参的填写
  • 完成HttpServletRequest 和 HttpServletResponse 的填写:就需要先拿到目的方法的全部参数。根据类型的名称 和 形参列表进行匹配 填写
  1. for (int i = 0; i < parameterTypes.length; i++) {<mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>Class parameterType = parameterTypes[i];<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>if ("HttpServletRequest".equals(parameterType.getSimpleName())) {<mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor><mvc:interceptor>
  22.     <mvc:mapping path="/h*"/>
  23.     <mvc:exclude-mapping path="/hello"/>
  24.     <ref bean="myInterceptor02"/>
  25. </mvc:interceptor>params[i] = request;<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  30. <beans>
  31.    
  32.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  33. </beans>} else if ("HttpServletResponse".equals(parameterType.getSimpleName())) {<mvc:interceptor>
  34.     <mvc:mapping path="/h*"/>
  35.     <mvc:exclude-mapping path="/hello"/>
  36.     <ref bean="myInterceptor02"/>
  37. </mvc:interceptor><mvc:interceptor>
  38.     <mvc:mapping path="/h*"/>
  39.     <mvc:exclude-mapping path="/hello"/>
  40.     <ref bean="myInterceptor02"/>
  41. </mvc:interceptor>params[i] = response;<mvc:interceptor>
  42.     <mvc:mapping path="/h*"/>
  43.     <mvc:exclude-mapping path="/hello"/>
  44.     <ref bean="myInterceptor02"/>
  45. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  46. <beans>
  47.    
  48.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  49. </beans>}<mvc:interceptor>
  50.     <mvc:mapping path="/h*"/>
  51.     <mvc:exclude-mapping path="/hello"/>
  52.     <ref bean="myInterceptor02"/>
  53. </mvc:interceptor>    }
复制代码

  • 完成带有@RequestParam注解的形参的填写:需要添加方法,获取目的方法中 带有@RequestParam注解的形参是属于第几个参数的,返回int 代表第几个参数,如果有@RequestParam注解,就会返回相应的索引,如果没有就会返回-1 进行普通方法参数的填写 处置处罚
  1. //获取目的方法中 带有@RequestParam注解的形参是属于第几个参数的,返 private int getRequestParamterIndex(Method method,String name){<mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor>Parameter[] parameters = method.getParameters();<mvc:interceptor>
  6.     <mvc:mapping path="/h*"/>
  7.     <mvc:exclude-mapping path="/hello"/>
  8.     <ref bean="myInterceptor02"/>
  9. </mvc:interceptor>for (int i = 0; i < parameters.length; i++) {<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor>    Parameter parameter = parameters[i];<mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor>    if (parameter.isAnnotationPresent(RequestParam.class)) {<mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  22. <beans>
  23.    
  24.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  25. </beans>String value = parameter.getAnnotation(RequestParam.class).value();<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  30. <beans>
  31.    
  32.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  33. </beans>if (name.equals(value)) {<mvc:interceptor>
  34.     <mvc:mapping path="/h*"/>
  35.     <mvc:exclude-mapping path="/hello"/>
  36.     <ref bean="myInterceptor02"/>
  37. </mvc:interceptor><mvc:interceptor>
  38.     <mvc:mapping path="/h*"/>
  39.     <mvc:exclude-mapping path="/hello"/>
  40.     <ref bean="myInterceptor02"/>
  41. </mvc:interceptor>return i;//返回int 代表第几个参数<mvc:interceptor>
  42.     <mvc:mapping path="/h*"/>
  43.     <mvc:exclude-mapping path="/hello"/>
  44.     <ref bean="myInterceptor02"/>
  45. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  46. <beans>
  47.    
  48.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  49. </beans>}<mvc:interceptor>
  50.     <mvc:mapping path="/h*"/>
  51.     <mvc:exclude-mapping path="/hello"/>
  52.     <ref bean="myInterceptor02"/>
  53. </mvc:interceptor>    }<?xml version="1.0" encoding="UTF-8" ?>
  54. <beans>
  55.    
  56.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  57. </beans>}<?xml version="1.0" encoding="UTF-8" ?>
  58. <beans>
  59.    
  60.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  61. </beans>return -1;    }
复制代码
  1. int requestParamterIndex = getRequestParamterIndex(zyHandler.getMethod(), name);<mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>if (requestParamterIndex != -1) {<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor><mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor>params[requestParamterIndex] = value;<mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  22. <beans>
  23.    
  24.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  25. </beans>}
复制代码

  • 普通方法参数的 填写:需要添加方法,将目的方法的全部的形参的名称 反射保存到 List 返回,再通过遍历判断 请求的参数名  和 List中一致的 填写到 数组中
  1. <bean >
  2.         <property name="order" value="99"></property>
  3. </bean>//将目的方法的全部的形参的名称 反射保存到 List 返回    private List getParameterNames(Method method){<?xml version="1.0" encoding="UTF-8" ?>
  4. <beans>
  5.    
  6.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  7. </beans>List parameterList = new ArrayList();<?xml version="1.0" encoding="UTF-8" ?>
  8. <beans>
  9.    
  10.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  11. </beans>//获取到全部的参数名称<?xml version="1.0" encoding="UTF-8" ?>
  12. <beans>
  13.    
  14.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  15. </beans>Parameter[] parameters = method.getParameters();<?xml version="1.0" encoding="UTF-8" ?>
  16. <beans>
  17.    
  18.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  19. </beans>for (Parameter parameter : parameters) {<mvc:interceptor>
  20.     <mvc:mapping path="/h*"/>
  21.     <mvc:exclude-mapping path="/hello"/>
  22.     <ref bean="myInterceptor02"/>
  23. </mvc:interceptor>//在默认情况下 parameter.getName() 获取的名字不是形参真正的名字<mvc:interceptor>
  24.     <mvc:mapping path="/h*"/>
  25.     <mvc:exclude-mapping path="/hello"/>
  26.     <ref bean="myInterceptor02"/>
  27. </mvc:interceptor>//而是[arg0,arg1,arg2...]<mvc:interceptor>
  28.     <mvc:mapping path="/h*"/>
  29.     <mvc:exclude-mapping path="/hello"/>
  30.     <ref bean="myInterceptor02"/>
  31. </mvc:interceptor>//需要插件,使用java8的特性 解决<mvc:interceptor>
  32.     <mvc:mapping path="/h*"/>
  33.     <mvc:exclude-mapping path="/hello"/>
  34.     <ref bean="myInterceptor02"/>
  35. </mvc:interceptor>String name = parameter.getName();<mvc:interceptor>
  36.     <mvc:mapping path="/h*"/>
  37.     <mvc:exclude-mapping path="/hello"/>
  38.     <ref bean="myInterceptor02"/>
  39. </mvc:interceptor>parameterList.add(name);<?xml version="1.0" encoding="UTF-8" ?>
  40. <beans>
  41.    
  42.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  43. </beans>}<?xml version="1.0" encoding="UTF-8" ?>
  44. <beans>
  45.    
  46.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  47. </beans>System.out.println("目的方法的形参列表=" + parameterList);<?xml version="1.0" encoding="UTF-8" ?>
  48. <beans>
  49.    
  50.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  51. </beans>return parameterList;    }
复制代码
  1. else {<mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor><mvc:interceptor>
  6.     <mvc:mapping path="/h*"/>
  7.     <mvc:exclude-mapping path="/hello"/>
  8.     <ref bean="myInterceptor02"/>
  9. </mvc:interceptor>//没找到@RequestParam 对应参数--使用默认机制<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor><mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor>//1. 得到目的方法的全部形参名<mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor><mvc:interceptor>
  22.     <mvc:mapping path="/h*"/>
  23.     <mvc:exclude-mapping path="/hello"/>
  24.     <ref bean="myInterceptor02"/>
  25. </mvc:interceptor>//2. 对得到目的方法的全部形参名进行遍历,<mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor><mvc:interceptor>
  30.     <mvc:mapping path="/h*"/>
  31.     <mvc:exclude-mapping path="/hello"/>
  32.     <ref bean="myInterceptor02"/>
  33. </mvc:interceptor>//如果匹配就把当前请求的参数值放入params<mvc:interceptor>
  34.     <mvc:mapping path="/h*"/>
  35.     <mvc:exclude-mapping path="/hello"/>
  36.     <ref bean="myInterceptor02"/>
  37. </mvc:interceptor><mvc:interceptor>
  38.     <mvc:mapping path="/h*"/>
  39.     <mvc:exclude-mapping path="/hello"/>
  40.     <ref bean="myInterceptor02"/>
  41. </mvc:interceptor>List parameterNames = getParameterNames(zyHandler.getMethod());<mvc:interceptor>
  42.     <mvc:mapping path="/h*"/>
  43.     <mvc:exclude-mapping path="/hello"/>
  44.     <ref bean="myInterceptor02"/>
  45. </mvc:interceptor><mvc:interceptor>
  46.     <mvc:mapping path="/h*"/>
  47.     <mvc:exclude-mapping path="/hello"/>
  48.     <ref bean="myInterceptor02"/>
  49. </mvc:interceptor>for (int i = 0; i < parameterNames.size(); i++) {
  50.     <bean id="messageSource" class=
  51. <mvc:interceptor>
  52.     <mvc:mapping path="/h*"/>
  53.     <mvc:exclude-mapping path="/hello"/>
  54.     <ref bean="myInterceptor02"/>
  55. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  56. <?xml version="1.0" encoding="UTF-8" ?>
  57. <beans>
  58.    
  59.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  60. </beans>
  61. <?xml version="1.0" encoding="UTF-8" ?>
  62. <beans>
  63.    
  64.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  65. </beans><property name="basename" value="i18n"></property>
  66.     </bean>   if (name.equals(parameterNames.get(i))) {    <bean >
  67.    
  68.    
  69. <?xml version="1.0" encoding="UTF-8" ?>
  70. <beans>
  71.    
  72.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  73. </beans><property name="prefix" value="/WEB-INF/pages/"/>
  74. <?xml version="1.0" encoding="UTF-8" ?>
  75. <beans>
  76.    
  77.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  78. </beans><property name="suffix" value=".jsp"/>
  79.     </bean>params[i] = value;    <bean >
  80.    
  81.    
  82. <?xml version="1.0" encoding="UTF-8" ?>
  83. <beans>
  84.    
  85.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  86. </beans><property name="prefix" value="/WEB-INF/pages/"/>
  87. <?xml version="1.0" encoding="UTF-8" ?>
  88. <beans>
  89.    
  90.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  91. </beans><property name="suffix" value=".jsp"/>
  92.     </bean>break;
  93.     <bean id="messageSource" class=
  94. <mvc:interceptor>
  95.     <mvc:mapping path="/h*"/>
  96.     <mvc:exclude-mapping path="/hello"/>
  97.     <ref bean="myInterceptor02"/>
  98. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  99. <?xml version="1.0" encoding="UTF-8" ?>
  100. <beans>
  101.    
  102.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  103. </beans>
  104. <?xml version="1.0" encoding="UTF-8" ?>
  105. <beans>
  106.    
  107.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  108. </beans><property name="basename" value="i18n"></property>
  109.     </bean>   }<mvc:interceptor>
  110.     <mvc:mapping path="/h*"/>
  111.     <mvc:exclude-mapping path="/hello"/>
  112.     <ref bean="myInterceptor02"/>
  113. </mvc:interceptor><mvc:interceptor>
  114.     <mvc:mapping path="/h*"/>
  115.     <mvc:exclude-mapping path="/hello"/>
  116.     <ref bean="myInterceptor02"/>
  117. </mvc:interceptor>}<mvc:interceptor>
  118.     <mvc:mapping path="/h*"/>
  119.     <mvc:exclude-mapping path="/hello"/>
  120.     <ref bean="myInterceptor02"/>
  121. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  122. <beans>
  123.    
  124.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  125. </beans>}
复制代码

  • 普通方法参数的 填写 需要插件,使用java8的特性 解决在默认情况下 parameter.getName() 获取的名字不是形参真正的名字,而是[arg0,arg1,arg2...]的问题
  1. <mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor>com.fasterxml.jackson.core      jackson-databind      2.14.0   
复制代码

  • 完整代码
  1. public void executeDispatch(HttpServletRequest request, HttpServletResponse response) {<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>ZyHandler zyHandler = getZyHandler(request);<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>try {<mvc:interceptor>
  10.     <mvc:mapping path="/h*"/>
  11.     <mvc:exclude-mapping path="/hello"/>
  12.     <ref bean="myInterceptor02"/>
  13. </mvc:interceptor>if (null == zyHandler) {<mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor>    response.getWriter().write("[size=6]404 NOT FOUND![/size]
  18. ");<mvc:interceptor>
  19.     <mvc:mapping path="/h*"/>
  20.     <mvc:exclude-mapping path="/hello"/>
  21.     <ref bean="myInterceptor02"/>
  22. </mvc:interceptor>} else {<mvc:interceptor>
  23.     <mvc:mapping path="/h*"/>
  24.     <mvc:exclude-mapping path="/hello"/>
  25.     <ref bean="myInterceptor02"/>
  26. </mvc:interceptor>    Method method = zyHandler.getMethod();<mvc:interceptor>
  27.     <mvc:mapping path="/h*"/>
  28.     <mvc:exclude-mapping path="/hello"/>
  29.     <ref bean="myInterceptor02"/>
  30. </mvc:interceptor>    Class[] parameterTypes = method.getParameterTypes();//形参数组<mvc:interceptor>
  31.     <mvc:mapping path="/h*"/>
  32.     <mvc:exclude-mapping path="/hello"/>
  33.     <ref bean="myInterceptor02"/>
  34. </mvc:interceptor>    Object[] params = new Object[parameterTypes.length];<mvc:interceptor>
  35.     <mvc:mapping path="/h*"/>
  36.     <mvc:exclude-mapping path="/hello"/>
  37.     <ref bean="myInterceptor02"/>
  38. </mvc:interceptor>    //遍历 parameterTypes<mvc:interceptor>
  39.     <mvc:mapping path="/h*"/>
  40.     <mvc:exclude-mapping path="/hello"/>
  41.     <ref bean="myInterceptor02"/>
  42. </mvc:interceptor>    //获取 HttpServletRequest , HttpServletResponse 在形参数组中的位置<mvc:interceptor>
  43.     <mvc:mapping path="/h*"/>
  44.     <mvc:exclude-mapping path="/hello"/>
  45.     <ref bean="myInterceptor02"/>
  46. </mvc:interceptor>    //将request 和 response 保存到  params相应的位置上<mvc:interceptor>
  47.     <mvc:mapping path="/h*"/>
  48.     <mvc:exclude-mapping path="/hello"/>
  49.     <ref bean="myInterceptor02"/>
  50. </mvc:interceptor>    for (int i = 0; i < parameterTypes.length; i++) {<mvc:interceptor>
  51.     <mvc:mapping path="/h*"/>
  52.     <mvc:exclude-mapping path="/hello"/>
  53.     <ref bean="myInterceptor02"/>
  54. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  55. <beans>
  56.    
  57.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  58. </beans>Class parameterType = parameterTypes[i];<mvc:interceptor>
  59.     <mvc:mapping path="/h*"/>
  60.     <mvc:exclude-mapping path="/hello"/>
  61.     <ref bean="myInterceptor02"/>
  62. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  63. <beans>
  64.    
  65.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  66. </beans>if ("HttpServletRequest".equals(parameterType.getSimpleName())) {<mvc:interceptor>
  67.     <mvc:mapping path="/h*"/>
  68.     <mvc:exclude-mapping path="/hello"/>
  69.     <ref bean="myInterceptor02"/>
  70. </mvc:interceptor><mvc:interceptor>
  71.     <mvc:mapping path="/h*"/>
  72.     <mvc:exclude-mapping path="/hello"/>
  73.     <ref bean="myInterceptor02"/>
  74. </mvc:interceptor>params[i] = request;<mvc:interceptor>
  75.     <mvc:mapping path="/h*"/>
  76.     <mvc:exclude-mapping path="/hello"/>
  77.     <ref bean="myInterceptor02"/>
  78. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  79. <beans>
  80.    
  81.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  82. </beans>} else if ("HttpServletResponse".equals(parameterType.getSimpleName())) {<mvc:interceptor>
  83.     <mvc:mapping path="/h*"/>
  84.     <mvc:exclude-mapping path="/hello"/>
  85.     <ref bean="myInterceptor02"/>
  86. </mvc:interceptor><mvc:interceptor>
  87.     <mvc:mapping path="/h*"/>
  88.     <mvc:exclude-mapping path="/hello"/>
  89.     <ref bean="myInterceptor02"/>
  90. </mvc:interceptor>params[i] = response;<mvc:interceptor>
  91.     <mvc:mapping path="/h*"/>
  92.     <mvc:exclude-mapping path="/hello"/>
  93.     <ref bean="myInterceptor02"/>
  94. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  95. <beans>
  96.    
  97.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  98. </beans>}<mvc:interceptor>
  99.     <mvc:mapping path="/h*"/>
  100.     <mvc:exclude-mapping path="/hello"/>
  101.     <ref bean="myInterceptor02"/>
  102. </mvc:interceptor>    }<mvc:interceptor>
  103.     <mvc:mapping path="/h*"/>
  104.     <mvc:exclude-mapping path="/hello"/>
  105.     <ref bean="myInterceptor02"/>
  106. </mvc:interceptor>    //获取request中的<mvc:interceptor>
  107.     <mvc:mapping path="/h*"/>
  108.     <mvc:exclude-mapping path="/hello"/>
  109.     <ref bean="myInterceptor02"/>
  110. </mvc:interceptor>    request.setCharacterEncoding("utf-8");<mvc:interceptor>
  111.     <mvc:mapping path="/h*"/>
  112.     <mvc:exclude-mapping path="/hello"/>
  113.     <ref bean="myInterceptor02"/>
  114. </mvc:interceptor>    Map parameterMap = request.getParameterMap();<mvc:interceptor>
  115.     <mvc:mapping path="/h*"/>
  116.     <mvc:exclude-mapping path="/hello"/>
  117.     <ref bean="myInterceptor02"/>
  118. </mvc:interceptor>    for (Map.Entry entry : parameterMap.entrySet()) {<mvc:interceptor>
  119.     <mvc:mapping path="/h*"/>
  120.     <mvc:exclude-mapping path="/hello"/>
  121.     <ref bean="myInterceptor02"/>
  122. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  123. <beans>
  124.    
  125.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  126. </beans>String name = entry.getKey();//参数 键<mvc:interceptor>
  127.     <mvc:mapping path="/h*"/>
  128.     <mvc:exclude-mapping path="/hello"/>
  129.     <ref bean="myInterceptor02"/>
  130. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  131. <beans>
  132.    
  133.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  134. </beans>String value = entry.getValue()[0];//参数 值<mvc:interceptor>
  135.     <mvc:mapping path="/h*"/>
  136.     <mvc:exclude-mapping path="/hello"/>
  137.     <ref bean="myInterceptor02"/>
  138. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  139. <beans>
  140.    
  141.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  142. </beans>//获取形参数组中 带有@RequestParam 的形参 的位置<mvc:interceptor>
  143.     <mvc:mapping path="/h*"/>
  144.     <mvc:exclude-mapping path="/hello"/>
  145.     <ref bean="myInterceptor02"/>
  146. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  147. <beans>
  148.    
  149.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  150. </beans>//将带有@RequestParam 保存到  params相应的位置上<mvc:interceptor>
  151.     <mvc:mapping path="/h*"/>
  152.     <mvc:exclude-mapping path="/hello"/>
  153.     <ref bean="myInterceptor02"/>
  154. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  155. <beans>
  156.    
  157.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  158. </beans>int requestParamterIndex = getRequestParamterIndex(zyHandler.getMethod(), name);<mvc:interceptor>
  159.     <mvc:mapping path="/h*"/>
  160.     <mvc:exclude-mapping path="/hello"/>
  161.     <ref bean="myInterceptor02"/>
  162. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  163. <beans>
  164.    
  165.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  166. </beans>if (requestParamterIndex != -1) {<mvc:interceptor>
  167.     <mvc:mapping path="/h*"/>
  168.     <mvc:exclude-mapping path="/hello"/>
  169.     <ref bean="myInterceptor02"/>
  170. </mvc:interceptor><mvc:interceptor>
  171.     <mvc:mapping path="/h*"/>
  172.     <mvc:exclude-mapping path="/hello"/>
  173.     <ref bean="myInterceptor02"/>
  174. </mvc:interceptor>params[requestParamterIndex] = value;<mvc:interceptor>
  175.     <mvc:mapping path="/h*"/>
  176.     <mvc:exclude-mapping path="/hello"/>
  177.     <ref bean="myInterceptor02"/>
  178. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  179. <beans>
  180.    
  181.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  182. </beans>} else {<mvc:interceptor>
  183.     <mvc:mapping path="/h*"/>
  184.     <mvc:exclude-mapping path="/hello"/>
  185.     <ref bean="myInterceptor02"/>
  186. </mvc:interceptor><mvc:interceptor>
  187.     <mvc:mapping path="/h*"/>
  188.     <mvc:exclude-mapping path="/hello"/>
  189.     <ref bean="myInterceptor02"/>
  190. </mvc:interceptor>//没找到@RequestParam 对应参数--使用默认机制<mvc:interceptor>
  191.     <mvc:mapping path="/h*"/>
  192.     <mvc:exclude-mapping path="/hello"/>
  193.     <ref bean="myInterceptor02"/>
  194. </mvc:interceptor><mvc:interceptor>
  195.     <mvc:mapping path="/h*"/>
  196.     <mvc:exclude-mapping path="/hello"/>
  197.     <ref bean="myInterceptor02"/>
  198. </mvc:interceptor>//1. 得到目的方法的全部形参名<mvc:interceptor>
  199.     <mvc:mapping path="/h*"/>
  200.     <mvc:exclude-mapping path="/hello"/>
  201.     <ref bean="myInterceptor02"/>
  202. </mvc:interceptor><mvc:interceptor>
  203.     <mvc:mapping path="/h*"/>
  204.     <mvc:exclude-mapping path="/hello"/>
  205.     <ref bean="myInterceptor02"/>
  206. </mvc:interceptor>//2. 对得到目的方法的全部形参名进行遍历,<mvc:interceptor>
  207.     <mvc:mapping path="/h*"/>
  208.     <mvc:exclude-mapping path="/hello"/>
  209.     <ref bean="myInterceptor02"/>
  210. </mvc:interceptor><mvc:interceptor>
  211.     <mvc:mapping path="/h*"/>
  212.     <mvc:exclude-mapping path="/hello"/>
  213.     <ref bean="myInterceptor02"/>
  214. </mvc:interceptor>//如果匹配就把当前请求的参数值放入params<mvc:interceptor>
  215.     <mvc:mapping path="/h*"/>
  216.     <mvc:exclude-mapping path="/hello"/>
  217.     <ref bean="myInterceptor02"/>
  218. </mvc:interceptor><mvc:interceptor>
  219.     <mvc:mapping path="/h*"/>
  220.     <mvc:exclude-mapping path="/hello"/>
  221.     <ref bean="myInterceptor02"/>
  222. </mvc:interceptor>List parameterNames = getParameterNames(zyHandler.getMethod());<mvc:interceptor>
  223.     <mvc:mapping path="/h*"/>
  224.     <mvc:exclude-mapping path="/hello"/>
  225.     <ref bean="myInterceptor02"/>
  226. </mvc:interceptor><mvc:interceptor>
  227.     <mvc:mapping path="/h*"/>
  228.     <mvc:exclude-mapping path="/hello"/>
  229.     <ref bean="myInterceptor02"/>
  230. </mvc:interceptor>for (int i = 0; i < parameterNames.size(); i++) {
  231.     <bean id="messageSource" class=
  232. <mvc:interceptor>
  233.     <mvc:mapping path="/h*"/>
  234.     <mvc:exclude-mapping path="/hello"/>
  235.     <ref bean="myInterceptor02"/>
  236. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  237. <?xml version="1.0" encoding="UTF-8" ?>
  238. <beans>
  239.    
  240.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  241. </beans>
  242. <?xml version="1.0" encoding="UTF-8" ?>
  243. <beans>
  244.    
  245.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  246. </beans><property name="basename" value="i18n"></property>
  247.     </bean>   if (name.equals(parameterNames.get(i))) {    <bean >
  248.    
  249.    
  250. <?xml version="1.0" encoding="UTF-8" ?>
  251. <beans>
  252.    
  253.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  254. </beans><property name="prefix" value="/WEB-INF/pages/"/>
  255. <?xml version="1.0" encoding="UTF-8" ?>
  256. <beans>
  257.    
  258.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  259. </beans><property name="suffix" value=".jsp"/>
  260.     </bean>params[i] = value;    <bean >
  261.    
  262.    
  263. <?xml version="1.0" encoding="UTF-8" ?>
  264. <beans>
  265.    
  266.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  267. </beans><property name="prefix" value="/WEB-INF/pages/"/>
  268. <?xml version="1.0" encoding="UTF-8" ?>
  269. <beans>
  270.    
  271.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  272. </beans><property name="suffix" value=".jsp"/>
  273.     </bean>break;
  274.     <bean id="messageSource" class=
  275. <mvc:interceptor>
  276.     <mvc:mapping path="/h*"/>
  277.     <mvc:exclude-mapping path="/hello"/>
  278.     <ref bean="myInterceptor02"/>
  279. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  280. <?xml version="1.0" encoding="UTF-8" ?>
  281. <beans>
  282.    
  283.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  284. </beans>
  285. <?xml version="1.0" encoding="UTF-8" ?>
  286. <beans>
  287.    
  288.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  289. </beans><property name="basename" value="i18n"></property>
  290.     </bean>   }<mvc:interceptor>
  291.     <mvc:mapping path="/h*"/>
  292.     <mvc:exclude-mapping path="/hello"/>
  293.     <ref bean="myInterceptor02"/>
  294. </mvc:interceptor><mvc:interceptor>
  295.     <mvc:mapping path="/h*"/>
  296.     <mvc:exclude-mapping path="/hello"/>
  297.     <ref bean="myInterceptor02"/>
  298. </mvc:interceptor>}<mvc:interceptor>
  299.     <mvc:mapping path="/h*"/>
  300.     <mvc:exclude-mapping path="/hello"/>
  301.     <ref bean="myInterceptor02"/>
  302. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  303. <beans>
  304.    
  305.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  306. </beans>}<mvc:interceptor>
  307.     <mvc:mapping path="/h*"/>
  308.     <mvc:exclude-mapping path="/hello"/>
  309.     <ref bean="myInterceptor02"/>
  310. </mvc:interceptor>    }
复制代码
视图解析

思路


  • 首先 视图解析 它是在分发请求后 在目的方法中进行视图的跳转 forward 或者 redirect,所以这部分的代码应该在 前端处置处罚器的executeDispatch 中 对目的方法进行反射后调用
  • 在对目的方法进行反射 method.invoke() 就会有返回值,根据返回值的类型进行相应业务处置处罚
  • 当返回的是String类型后 我们就可以根据 splic(":")进行分隔
  • splic(":")[0] 就是进行跳转的方式 forward 或者 redirect
  • splic(":")[1] 就是进行跳转的页面
  • 如果没有":" ,就分析是默认情况,forward 处置处罚即可
实现


  • 首先 视图解析 它是在分发请求后 在目的方法中进行视图的跳转 forward 或者 redirect,所以这部分的代码应该在 前端处置处罚器的executeDispatch 中 对目的方法进行反射后调用
  • 在对目的方法进行反射 method.invoke() 就会有返回值,根据返回值的类型进行相应业务处置处罚
    1. Object result = zyHandler.getMethod().invoke(zyHandler.getController(), params);
    复制代码
  • 当返回的是String类型后 我们就可以根据 splic(":")进行分隔
  • splic(":")[0] 就是进行跳转的方式 forward 或者 redirect
  • splic(":")[1] 就是进行跳转的页面
  • 如果没有":" ,就分析是默认情况,forward 处置处罚即可
  1. if (result instanceof String){<mvc:interceptor>
  2.     <mvc:mapping path="/h*"/>
  3.     <mvc:exclude-mapping path="/hello"/>
  4.     <ref bean="myInterceptor02"/>
  5. </mvc:interceptor>       String viewName =  (String) result;<mvc:interceptor>
  6.     <mvc:mapping path="/h*"/>
  7.     <mvc:exclude-mapping path="/hello"/>
  8.     <ref bean="myInterceptor02"/>
  9. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>if (viewName.contains(":")) {<mvc:interceptor>
  14.     <mvc:mapping path="/h*"/>
  15.     <mvc:exclude-mapping path="/hello"/>
  16.     <ref bean="myInterceptor02"/>
  17. </mvc:interceptor><mvc:interceptor>
  18.     <mvc:mapping path="/h*"/>
  19.     <mvc:exclude-mapping path="/hello"/>
  20.     <ref bean="myInterceptor02"/>
  21. </mvc:interceptor>String viewType = viewName.split(":")[0];<mvc:interceptor>
  22.     <mvc:mapping path="/h*"/>
  23.     <mvc:exclude-mapping path="/hello"/>
  24.     <ref bean="myInterceptor02"/>
  25. </mvc:interceptor><mvc:interceptor>
  26.     <mvc:mapping path="/h*"/>
  27.     <mvc:exclude-mapping path="/hello"/>
  28.     <ref bean="myInterceptor02"/>
  29. </mvc:interceptor>String viewPage = viewName.split(":")[1];<mvc:interceptor>
  30.     <mvc:mapping path="/h*"/>
  31.     <mvc:exclude-mapping path="/hello"/>
  32.     <ref bean="myInterceptor02"/>
  33. </mvc:interceptor><mvc:interceptor>
  34.     <mvc:mapping path="/h*"/>
  35.     <mvc:exclude-mapping path="/hello"/>
  36.     <ref bean="myInterceptor02"/>
  37. </mvc:interceptor>if ("forward".equals(viewType)){
  38.     <bean id="messageSource" class=
  39. <mvc:interceptor>
  40.     <mvc:mapping path="/h*"/>
  41.     <mvc:exclude-mapping path="/hello"/>
  42.     <ref bean="myInterceptor02"/>
  43. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  44. <?xml version="1.0" encoding="UTF-8" ?>
  45. <beans>
  46.    
  47.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  48. </beans>
  49. <?xml version="1.0" encoding="UTF-8" ?>
  50. <beans>
  51.    
  52.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  53. </beans><property name="basename" value="i18n"></property>
  54.     </bean>   request.getRequestDispatcher(viewPage).forward(request,response);<mvc:interceptor>
  55.     <mvc:mapping path="/h*"/>
  56.     <mvc:exclude-mapping path="/hello"/>
  57.     <ref bean="myInterceptor02"/>
  58. </mvc:interceptor><mvc:interceptor>
  59.     <mvc:mapping path="/h*"/>
  60.     <mvc:exclude-mapping path="/hello"/>
  61.     <ref bean="myInterceptor02"/>
  62. </mvc:interceptor>}else if (("redirect".equals(viewType))){
  63.     <bean id="messageSource" class=
  64. <mvc:interceptor>
  65.     <mvc:mapping path="/h*"/>
  66.     <mvc:exclude-mapping path="/hello"/>
  67.     <ref bean="myInterceptor02"/>
  68. </mvc:interceptor>"org.springframework.context.support.ResourceBundleMessageSource">
  69. <?xml version="1.0" encoding="UTF-8" ?>
  70. <beans>
  71.    
  72.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  73. </beans>
  74. <?xml version="1.0" encoding="UTF-8" ?>
  75. <beans>
  76.    
  77.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  78. </beans><property name="basename" value="i18n"></property>
  79.     </bean>   response.sendRedirect(viewPage);<mvc:interceptor>
  80.     <mvc:mapping path="/h*"/>
  81.     <mvc:exclude-mapping path="/hello"/>
  82.     <ref bean="myInterceptor02"/>
  83. </mvc:interceptor><mvc:interceptor>
  84.     <mvc:mapping path="/h*"/>
  85.     <mvc:exclude-mapping path="/hello"/>
  86.     <ref bean="myInterceptor02"/>
  87. </mvc:interceptor>}<mvc:interceptor>
  88.     <mvc:mapping path="/h*"/>
  89.     <mvc:exclude-mapping path="/hello"/>
  90.     <ref bean="myInterceptor02"/>
  91. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  92. <beans>
  93.    
  94.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  95. </beans>}else {<mvc:interceptor>
  96.     <mvc:mapping path="/h*"/>
  97.     <mvc:exclude-mapping path="/hello"/>
  98.     <ref bean="myInterceptor02"/>
  99. </mvc:interceptor><mvc:interceptor>
  100.     <mvc:mapping path="/h*"/>
  101.     <mvc:exclude-mapping path="/hello"/>
  102.     <ref bean="myInterceptor02"/>
  103. </mvc:interceptor>request.getRequestDispatcher(viewName).forward(request,response);<mvc:interceptor>
  104.     <mvc:mapping path="/h*"/>
  105.     <mvc:exclude-mapping path="/hello"/>
  106.     <ref bean="myInterceptor02"/>
  107. </mvc:interceptor><?xml version="1.0" encoding="UTF-8" ?>
  108. <beans>
  109.    
  110.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  111. </beans>}<mvc:interceptor>
  112.     <mvc:mapping path="/h*"/>
  113.     <mvc:exclude-mapping path="/hello"/>
  114.     <ref bean="myInterceptor02"/>
  115. </mvc:interceptor>    }
复制代码
@ResponseBody 返回JSON数据

实现


  • 首先@ResponseBody  是写在方法上的 因此 @Target(ElementType.METHOD)
  • 没有默认值 @ResponseBody仅仅作为一个标识
  • @ResponseBody它是在分发请求后 在目的方法中标识该方法返回JSON格式的数据给浏览器,所以这部分的代码应该在 前端处置处罚器的executeDispatch 中 对目的方法进行反射后调用
  • 在对目的方法进行反射 method.invoke() 就会有返回值,根据返回值的类型进行相应业务处置处罚
  • 当返回的是一个集合类型,而且判断该方法有注解@ResponseBody ,就分析是需要向浏览器返回JSON格式数据
  • 用jackson 包下的 objectWriter对象的 objectMapper.writeValueAsString()方法 ,可以很轻松的将集合转化为JSON进行返回
  • 不要忘了设置response格式,防止乱码,response.setContentType("text/html;charset=utf-8");
  • 直接用response.getWriter.writer()将转化后的结果返回给浏览器即可
思路


  • 首先@ResponseBody  是写在方法上的 因此 @Target(ElementType.METHOD)
  • 没有默认值 @ResponseBody仅仅作为一个标识
  1. @Target(ElementType.METHOD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface ResponseBody {
  5. }
复制代码

  • @ResponseBody它是在分发请求后 在目的方法中标识该方法返回JSON格式的数据给浏览器,所以这部分的代码应该在 前端处置处罚器的executeDispatch 中 对目的方法进行反射后调用
  • 在对目的方法进行反射 method.invoke() 就会有返回值,根据返回值的类型进行相应业务处置处罚
  • 当返回的是一个集合类型,而且判断该方法有注解@ResponseBody ,就分析是需要向浏览器返回JSON格式数据
  • 用jackson 包下的 objectWriter对象的 objectMapper.writeValueAsString()方法 ,可以很轻松的将集合转化为JSON进行返回
  1. else if (result instanceof ArrayList) {    if (zyHandler.getMethod().isAnnotationPresent(ResponseBody.class)) {<?xml version="1.0" encoding="UTF-8" ?>
  2. <beans>
  3.    
  4.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  5. </beans>ObjectMapper objectMapper = new ObjectMapper();<?xml version="1.0" encoding="UTF-8" ?>
  6. <beans>
  7.    
  8.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  9. </beans>String json = objectMapper.writeValueAsString(result);<?xml version="1.0" encoding="UTF-8" ?>
  10. <beans>
  11.    
  12.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  13. </beans>response.setContentType("text/html;charset=utf-8");<?xml version="1.0" encoding="UTF-8" ?>
  14. <beans>
  15.    
  16.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  17. </beans>PrintWriter writer = response.getWriter();<?xml version="1.0" encoding="UTF-8" ?>
  18. <beans>
  19.    
  20.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  21. </beans>writer.write(json);<?xml version="1.0" encoding="UTF-8" ?>
  22. <beans>
  23.    
  24.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  25. </beans>writer.flush();<?xml version="1.0" encoding="UTF-8" ?>
  26. <beans>
  27.    
  28.     <component-scan base-package="com.code_study.controller,com.code_study.service"></component-scan>
  29. </beans>writer.close();    }}
复制代码

  • 不要忘了设置response格式,防止乱码,response.setContentType("text/html;charset=utf-8");
  • 直接用response.getWriter.writer()将转化后的结果返回给浏览器即可
本文学习内容来自韩顺平老师的课程
仅供个人参考学习

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

数据人与超自然意识

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表