Spring MVC 自定义数据绑定---HandlerMethodArgumentResolver

转载自:http://blog.csdn.net/linuu/article/details/51065476 谢谢作者的分享

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

认识HandlerMethodArgumentResolver,我们可以看下HandlerMethodArgumentResolver的继承关系图
这里写图片描述

我们可以很清楚的看到我们常见的几个数据绑定的annotation的具体实现都是实现了HandlerMethodArgumentResolver这个接口,我们可以先尝试一下写一个demo,自定义annotation绑定一个数据
首先我们新建一个annotation—–CurrentUser 默认只能注解参数,且运行时有效:

import java.lang.annotation.Documented;  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
@Target({ElementType.PARAMETER})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface CurrentUser {  


    String value() default "";  

}  

我们按照他的定义,自定义一个CurrentUserHandlerMethodArgumentResolver实现HandlerMethodArgumentResolver:

import org.springframework.core.MethodParameter;  
import org.springframework.web.bind.support.WebDataBinderFactory;  
import org.springframework.web.context.request.NativeWebRequest;  
import org.springframework.web.method.support.HandlerMethodArgumentResolver;  
import org.springframework.web.method.support.ModelAndViewContainer;  
import org.study.lyncc.web.entity.User;  
import org.study.lyncc.web.resolver.annotation.CurrentUser;  

public class CurrentUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver{  

    public boolean supportsParameter(MethodParameter parameter) {  
        return parameter.hasParameterAnnotation(CurrentUser.class);  
    }  

    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,  
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {  
        return new User(1,"lyncc");  
    }  

}  

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

import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.servlet.ModelAndView;  
import org.study.lyncc.web.entity.User;  
import org.study.lyncc.web.resolver.annotation.CurrentUser;  

@Controller  
@RequestMapping(value="/data/binding")  
public class CostomDataBindingController {  

    @RequestMapping(value="/test")  
    public ModelAndView costomData(@CurrentUser User u){  
        System.out.println(u.getUsername());  
        ModelAndView mav = new ModelAndView("session");  
        return mav;  
    }  

}  

我们写了一个测试方法,costomData中间的入参是User,前面加了我们自定义的注解@CurrentUser,这样此处的User应该就是我们在CurrentUserHandlerMethodArgumentResolver中resolveArgument方法返回的对象了
不过我们还需要让spring容器加载我们自定义的数据绑定的类CurrentUserHandlerMethodArgumentResolver,我们修改一下我们spring mvc的配置文件spring-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xmlns:p="http://www.springframework.org/schema/p"  
       xmlns:context="http://www.springframework.org/schema/context"  
       xmlns:mvc="http://www.springframework.org/schema/mvc"  
       xsi:schemaLocation="  
       http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans.xsd  
       http://www.springframework.org/schema/context  
       http://www.springframework.org/schema/context/spring-context.xsd  
       http://www.springframework.org/schema/mvc  
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">  

     <!-- 基于注解驱动 -->  
    <mvc:annotation-driven>  
       <mvc:argument-resolvers>    
            <bean class="org.study.lyncc.web.resolver.CurrentUserHandlerMethodArgumentResolver"/>    
        </mvc:argument-resolvers>    
    </mvc:annotation-driven>  

    <!-- 默认spring的扫描包, 此处指定处理扫描org.study.lyncc.web.controller包下的类有@Controller注解的-->  
     <context:component-scan base-package="org.study.lyncc.web.controller" >  
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />   
    </context:component-scan>    

    <!-- 静态资源的处理 -->  
    <mvc:resources mapping="/fonts/**" location="/WEB-INF/fonts/"/>  
    <mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>  

     <!--视图解析器  -->  
    <bean id="viewResolver"    
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">    
        <property name="prefix" value="/WEB-INF/jsp/"></property>    
        <property name="suffix" value=".jsp"></property>    
    </bean>   

</beans>  

在中加入我们的自定义的类的全路径
启动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

import java.lang.annotation.Documented;  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  


@Target({ElementType.PARAMETER})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface ManyUser {  

    String value() default "";  
}  

ManyUserHandlerMethodArgumentResolver

import java.util.ArrayList;  
import java.util.List;  

import org.springframework.core.MethodParameter;  
import org.springframework.web.bind.support.WebDataBinderFactory;  
import org.springframework.web.context.request.NativeWebRequest;  
import org.springframework.web.method.support.HandlerMethodArgumentResolver;  
import org.springframework.web.method.support.ModelAndViewContainer;  
import org.study.lyncc.web.entity.User;  
import org.study.lyncc.web.resolver.annotation.ManyUser;  

public class ManyUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver{  

    public boolean supportsParameter(MethodParameter parameter) {  
        return parameter.hasParameterAnnotation(ManyUser.class);  
    }  

    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,  
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {  
        List<User> users = new ArrayList<User>();  
        String names = (String)webRequest.getParameter("names");  
        String ids = (String)webRequest.getParameter("ids");  
        if(null != names && null != ids){  
            String[] nameStrs = names.trim().split(",");  
            String[] idStrs = ids.trim().split(",");  
            for(int i = 0;i<nameStrs.length;i++){  
                User user = new User(Integer.parseInt(idStrs[i]), nameStrs[i]);  
                users.add(user);  
            }  
        }  
        return users;  
    }  

}  

测试controller

import java.util.List;  

import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.servlet.ModelAndView;  
import org.study.lyncc.web.entity.User;  
import org.study.lyncc.web.resolver.annotation.CurrentUser;  
import org.study.lyncc.web.resolver.annotation.ManyUser;  

@Controller  
@RequestMapping(value="/data/binding")  
public class CostomDataBindingController {  

    @RequestMapping(value="/test")  
    public ModelAndView costomData(@CurrentUser User u){  
        System.out.println(u.getUsername());  
        ModelAndView mav = new ModelAndView("session");  
        return mav;  
    }  

    @RequestMapping(value="/custom")  
    public ModelAndView customData1(@ManyUser List<User> users){  
        if(null != users && !users.isEmpty()){  
            for(User u : users){  
                System.out.println(u);  
            }  
        }  
        ModelAndView mav = new ModelAndView("session");  
        return mav;  
    }  


}

别忘记修改spring-servlet.xml

<mvc:annotation-driven>  
     <mvc:argument-resolvers>    
          <bean class="org.study.lyncc.web.resolver.CurrentUserHandlerMethodArgumentResolver"/>  
          <bean class="org.study.lyncc.web.resolver.ManyUserHandlerMethodArgumentResolver"/>    
      </mvc:argument-resolvers>    
  </mvc:annotation-driven>  

启动项目,输入
http://localhost:8080/spring-mvc/data/binding/custom?names=lyncc,fly,ted&ids=1,2,3
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值