自定义数据绑定---HandlerMethodArgumentResolver

来源:互联网 发布:数据库exists 编辑:程序博客网 时间:2024/05/21 09:32

介绍

      前面几节我们介绍了spring MVC的几种常见的数据绑定的方法,可以灵活地获取用户请求中的参数,例如@PathVariable,@ModelAttribute,@RequestParam等这些数据绑定注解,有了这些注解,我们可以很方便的去获取参数,但是偶尔我们需要自定义的去进行数据绑定,Spring一直遵循开闭原则,可以让使用者自定义去做自己的事情,今天我们一起浅析一下HandlerMethodArgumentResolver



认识HandlerMethodArgumentResolver,我们可以看下HandlerMethodArgumentResolver的继承关系图

我们可以很清楚的看到我们常见的几个数据绑定的annotation的具体实现都是实现了HandlerMethodArgumentResolver这个接口,我们可以先尝试一下写一个demo,自定义annotation绑定一个数据

首先我们新建一个annotation-----CurrentUser  默认只能注解参数,且运行时有效:

[java] view plain copy
  1. package org.study.lyncc.web.resolver.annotation;  
  2.   
  3. import java.lang.annotation.Documented;  
  4. import java.lang.annotation.ElementType;  
  5. import java.lang.annotation.Retention;  
  6. import java.lang.annotation.RetentionPolicy;  
  7. import java.lang.annotation.Target;  
  8. @Target({ElementType.PARAMETER})  
  9. @Retention(RetentionPolicy.RUNTIME)  
  10. @Documented  
  11. public @interface CurrentUser {  
  12.   
  13.       
  14.     String value() default "";  
  15.   
  16. }  
我们按照他的定义,自定义一个CurrentUserHandlerMethodArgumentResolver实现HandlerMethodArgumentResolver:

[java] view plain copy
  1. package org.study.lyncc.web.resolver;  
  2.   
  3. import org.springframework.core.MethodParameter;  
  4. import org.springframework.web.bind.support.WebDataBinderFactory;  
  5. import org.springframework.web.context.request.NativeWebRequest;  
  6. import org.springframework.web.method.support.HandlerMethodArgumentResolver;  
  7. import org.springframework.web.method.support.ModelAndViewContainer;  
  8. import org.study.lyncc.web.entity.User;  
  9. import org.study.lyncc.web.resolver.annotation.CurrentUser;  
  10.   
  11. public class CurrentUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver{  
  12.   
  13.     public boolean supportsParameter(MethodParameter parameter) {  
  14.         return parameter.hasParameterAnnotation(CurrentUser.class);  
  15.     }  
  16.   
  17.     public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,  
  18.             NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {  
  19.         return new User(1,"lyncc");  
  20.     }  
  21.   
  22. }  

这边只是一个简单的demo,默认返回一个user,这样,我们写个controller来测试一下

[java] view plain copy
  1. package org.study.lyncc.web.controller;  
  2.   
  3. import org.springframework.stereotype.Controller;  
  4. import org.springframework.web.bind.annotation.RequestMapping;  
  5. import org.springframework.web.servlet.ModelAndView;  
  6. import org.study.lyncc.web.entity.User;  
  7. import org.study.lyncc.web.resolver.annotation.CurrentUser;  
  8.   
  9. @Controller  
  10. @RequestMapping(value="/data/binding")  
  11. public class CostomDataBindingController {  
  12.       
  13.     @RequestMapping(value="/test")  
  14.     public ModelAndView costomData(@CurrentUser User u){  
  15.         System.out.println(u.getUsername());  
  16.         ModelAndView mav = new ModelAndView("session");  
  17.         return mav;  
  18.     }  
  19.   
  20. }  
我们写了一个测试方法,costomData中间的入参是User,前面加了我们自定义的注解@CurrentUser,这样此处的User应该就是我们在CurrentUserHandlerMethodArgumentResolver中resolveArgument方法返回的对象了

不过我们还需要让spring容器加载我们自定义的数据绑定的类CurrentUserHandlerMethodArgumentResolver,我们修改一下我们spring mvc的配置文件spring-servlet.xml

[html] view plain copy
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.        xmlns:p="http://www.springframework.org/schema/p"  
  4.        xmlns:context="http://www.springframework.org/schema/context"  
  5.        xmlns:mvc="http://www.springframework.org/schema/mvc"  
  6.        xsi:schemaLocation="  
  7.        http://www.springframework.org/schema/beans  
  8.        http://www.springframework.org/schema/beans/spring-beans.xsd  
  9.        http://www.springframework.org/schema/context  
  10.        http://www.springframework.org/schema/context/spring-context.xsd  
  11.        http://www.springframework.org/schema/mvc  
  12.        http://www.springframework.org/schema/mvc/spring-mvc.xsd">  
  13.          
  14.      <!-- 基于注解驱动 -->  
  15.     <mvc:annotation-driven>  
  16.        <mvc:argument-resolvers>    
  17.             <bean class="org.study.lyncc.web.resolver.CurrentUserHandlerMethodArgumentResolver"/>    
  18.         </mvc:argument-resolvers>    
  19.     </mvc:annotation-driven>  
  20.       
  21.     <!-- 默认spring的扫描包, 此处指定处理扫描org.study.lyncc.web.controller包下的类有@Controller注解的-->  
  22.      <context:component-scan base-package="org.study.lyncc.web.controller" >  
  23.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />   
  24.     </context:component-scan>    
  25.       
  26.     <!-- 静态资源的处理 -->  
  27.     <mvc:resources mapping="/fonts/**" location="/WEB-INF/fonts/"/>  
  28.     <mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>  
  29.   
  30.      <!--视图解析器  -->  
  31.     <bean id="viewResolver"    
  32.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">    
  33.         <property name="prefix" value="/WEB-INF/jsp/"></property>    
  34.         <property name="suffix" value=".jsp"></property>    
  35.     </bean>   
  36.       
  37. </beans>  
在<mvc:annotation-driven>中加入我们的自定义的类的全路径

启动spring mvc 浏览器中输入:http://localhost:8080/spring-mvc/data/binding/test,发现在控制台中正常打印了



好了,我们再举一个例子,加入我们的url是http://localhost:8080/spring-mvc/data/binding/custom?names=lyncc,fly,ted&ids=1,2,3,我们想要在后台直接获取一个List<User>

也就说我们可以提前转化

同样我们定义一个annotation

[java] view plain copy
  1. package org.study.lyncc.web.resolver.annotation;  
  2.   
  3. import java.lang.annotation.Documented;  
  4. import java.lang.annotation.ElementType;  
  5. import java.lang.annotation.Retention;  
  6. import java.lang.annotation.RetentionPolicy;  
  7. import java.lang.annotation.Target;  
  8.   
  9.   
  10. @Target({ElementType.PARAMETER})  
  11. @Retention(RetentionPolicy.RUNTIME)  
  12. @Documented  
  13. public @interface ManyUser {  
  14.   
  15.     String value() default "";  
  16. }  
ManyUserHandlerMethodArgumentResolver

[java] view plain copy
  1. package org.study.lyncc.web.resolver;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import org.springframework.core.MethodParameter;  
  7. import org.springframework.web.bind.support.WebDataBinderFactory;  
  8. import org.springframework.web.context.request.NativeWebRequest;  
  9. import org.springframework.web.method.support.HandlerMethodArgumentResolver;  
  10. import org.springframework.web.method.support.ModelAndViewContainer;  
  11. import org.study.lyncc.web.entity.User;  
  12. import org.study.lyncc.web.resolver.annotation.ManyUser;  
  13.   
  14. public class ManyUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver{  
  15.   
  16.     public boolean supportsParameter(MethodParameter parameter) {  
  17.         return parameter.hasParameterAnnotation(ManyUser.class);  
  18.     }  
  19.   
  20.     public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,  
  21.             NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {  
  22.         List<User> users = new ArrayList<User>();  
  23.         String names = (String)webRequest.getParameter("names");  
  24.         String ids = (String)webRequest.getParameter("ids");  
  25.         if(null != names && null != ids){  
  26.             String[] nameStrs = names.trim().split(",");  
  27.             String[] idStrs = ids.trim().split(",");  
  28.             for(int i = 0;i<nameStrs.length;i++){  
  29.                 User user = new User(Integer.parseInt(idStrs[i]), nameStrs[i]);  
  30.                 users.add(user);  
  31.             }  
  32.         }  
  33.         return users;  
  34.     }  
  35.   
  36. }  

测试controller

[java] view plain copy
  1. package org.study.lyncc.web.controller;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.springframework.stereotype.Controller;  
  6. import org.springframework.web.bind.annotation.RequestMapping;  
  7. import org.springframework.web.servlet.ModelAndView;  
  8. import org.study.lyncc.web.entity.User;  
  9. import org.study.lyncc.web.resolver.annotation.CurrentUser;  
  10. import org.study.lyncc.web.resolver.annotation.ManyUser;  
  11.   
  12. @Controller  
  13. @RequestMapping(value="/data/binding")  
  14. public class CostomDataBindingController {  
  15.       
  16.     @RequestMapping(value="/test")  
  17.     public ModelAndView costomData(@CurrentUser User u){  
  18.         System.out.println(u.getUsername());  
  19.         ModelAndView mav = new ModelAndView("session");  
  20.         return mav;  
  21.     }  
  22.       
  23.     @RequestMapping(value="/custom")  
  24.     public ModelAndView customData1(@ManyUser List<User> users){  
  25.         if(null != users && !users.isEmpty()){  
  26.             for(User u : users){  
  27.                 System.out.println(u);  
  28.             }  
  29.         }  
  30.         ModelAndView mav = new ModelAndView("session");  
  31.         return mav;  
  32.     }  
  33.   
  34.       
  35. }  
别忘记修改spring-servlet.xml

[html] view plain copy
  1. <mvc:annotation-driven>  
  2.      <mvc:argument-resolvers>    
  3.           <bean class="org.study.lyncc.web.resolver.CurrentUserHandlerMethodArgumentResolver"/>  
  4.           <bean class="org.study.lyncc.web.resolver.ManyUserHandlerMethodArgumentResolver"/>    
  5.       </mvc:argument-resolvers>    
  6.   </mvc:annotation-driven>  
启动项目,输入http://localhost:8080/spring-mvc/data/binding/custom?names=lyncc,fly,ted&ids=1,2,3







0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 脑袋撞了个包怎么办 交通事故对方全责但不赔偿怎么办 人格分列症的症状怎么办 子宫肌瘤月经量多怎么办 卵泡长得太慢怎么办 后期卵泡长得慢怎么办 促排卵泡长得慢怎么办 子宫内膜薄要怎么办啊 hcg值正常孕酮低怎么办 20号染色体三体怎么办 14号染色体三体怎么办 怀孕七个月不想要了怎么办 胎儿性染色体45x怎么办 16号染色体偏多怎么办 大拇指又短又宽怎么办 削山药皮皮肤痒怎么办 脊柱侧弯20度怎么办 27岁脊柱侧弯怎么办 右侧侧脑室增宽怎么办 左侧脑室增宽该怎么办 腿上的血管堵塞怎么办 做b超看不清骶尾怎么办 孕中期羊水过少怎么办 心脏办膜关闭不全怎么办 9个月胎儿脑积水怎么办 怀孕三个月胎盘低置怎么办 怀孕第一个月打针了怎么办 唐氏筛查神经管缺陷高风险怎么办 门诊处方笺丢了怎么办 孕中期睡觉手麻怎么办 怀孕2个月了没胎心胎芽怎么办 怀孕腿疼的厉害怎么办 孕妇老是失眠多梦怎么办 孕妇会失眠多梦怎么办 怀孕5个月睡不着怎么办 6个月孕妇失眠怎么办 彩超脉络丛囊肿怎么办 双侧脉络丛囊肿怎么办 唐筛神经管缺陷高风险怎么办 雌激素低怎么办吃什么东西补 我怀了狗的孩子怎么办