Spring MVC系列(五)之自定义数据绑定---HandlerMethodArgumentResolver

原创 2016年04月05日 16:00:01

介绍

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



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

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

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

package org.study.lyncc.web.resolver.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 CurrentUser {

    
    String value() default "";

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

package org.study.lyncc.web.resolver;

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来测试一下

package org.study.lyncc.web.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>
在<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

package org.study.lyncc.web.resolver.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

package org.study.lyncc.web.resolver;

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

package org.study.lyncc.web.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










版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

java SpringmvcAOP拦截Controller,获取session(自定义注解的方式)

项目纵览 第一步创建 packageorg.cyxl.spring.controller;     importjavax.servlet.http.HttpServletReq...

Spring MVC系列(三)之获取参数

介绍       Spring MVC的数据绑定功能做的很是强大,提供开发者以多种形式去获取页面传递过来的参数,今天我们一起看下spring支持以哪些方式获取值 ①当我们业务场景是根据user...
  • linuu
  • linuu
  • 2016-04-01 13:12
  • 659

Spring MVC系列(四)之session处理---@SessionAttributes

介绍        在web开发中,session的重要性不言而喻,与cookie相比,session更加安全,处于服务器端,开发者经常把一些重要的信息放在session,方便在多次请求中方便的获取...
  • linuu
  • linuu
  • 2016-04-01 16:34
  • 2065

使用springMVC框架时,怎样在controller里获得Session

需求: 使用springMVC框架时,怎样在controller里获得Session。 一、如果需要把某个命令对象放到session里面,完全可以去类上加@SessionAttributes,...

C#加密解密过程

加密代码 public static string Encode(string str, string key) { DESCryptoSe...

做一个合格的程序猿之MYSQL 使用心得(一)

开篇介绍,本人2014年6月毕业,目前一年半开发经验,来二流互联网工作一年,职位为典型的JAVA WEB 典型的CRUD选手。 今天分享一下入职以来,自己对mysql使用的心得,有错的地方,大家一起学...
  • linuu
  • linuu
  • 2016-03-03 09:23
  • 654

安装ubuntu Linux系统

/*适用于已安装其它版本的Linux,由grub引导系统启动*/1,将ubuntu.iso光盘镜像文件放到某个分区的根目录下,如D:/ubuntu.iso。将镜像文件中casper文件夹下的vmlin...

做一个合格的程序猿之浅析Spring AOP源码(十四) 分析ProxyFactoryBean

最基本的实现有三个,AspectJProxyFactory.java ,ProxyFactory.java ProxyFactoryBean这三个,他们的父类ProxyCreatorSupport只是...
  • linuu
  • linuu
  • 2016-03-24 15:20
  • 2828

Spring MVC系列(二)之@RequestMapping和URL映射

@RequestMapping是一个用来处理请求地址映射的注解,可以注解与类上,也可以注解与类中的方法上,注解与类上,表示该Controller的统一标识,通常表示一个模块的表示,注解在方法,则表示某...
  • linuu
  • linuu
  • 2016-03-31 09:40
  • 1703
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)