文档章节

spring的annotation-driven

dxbj1010
 dxbj1010
发布于 2016/05/09 21:16
字数 734
阅读 85
收藏 3

argument resolvers


  1.   spring的请求处理都是方法级别,围绕方法上的处理,当你需要针对请求参数做一些特殊的处理,不同的类型获得不同的处理。我这边项目有一个需求是在controller里面获得session里面的用户信息,我们普通采用的方法是直接从session里面获取,需要指定具体的key。从里面获得,如果调用登录用户的地方很多的时候,处理的逻辑也是相当冗余的。
  2. 这边利用spring的argument resolvers(参数解析),针对自定义注解来注入用户到方法级别。

     先定义注解:


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



里面可以扩展你需要对用户处理的逻辑。


在是实现spring的HandlerMethodArgumentResolver --这个接口是操作处理方法的参数处理。

spring在处理请求参数时,针对不同注解或者不同类型例如HttpRequest,HttpResponse的值的赋值。默认都是有一个组合的处理器,注册一些默认的处理方式,我下面把注册的地方添加进来。

在RequestMappingHandlerAdapter类里面的afterPropertiesSet方法里面。

public void afterPropertiesSet() {
		// Do this first, it may add ResponseBody advice beans
		initControllerAdviceCache();
                //请求参数初始的解析器
             if (this.argumentResolvers == null) {
			List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
			this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
                //初始绑定参数的解析器
		if (this.initBinderArgumentResolvers == null) {
			List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
			this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
                //初始方法返回值的包装器
		if (this.returnValueHandlers == null) {
			List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
			this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
		}
	}


每一个都有一个默认配置,以下是请求参数的默认解析器。

private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
		List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();

		// Annotation-based argument resolution
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); --@requestParam注解
		resolvers.add(new RequestParamMapMethodArgumentResolver());
		resolvers.add(new PathVariableMethodArgumentResolver());--@pathVariable注解
		resolvers.add(new PathVariableMapMethodArgumentResolver());
		resolvers.add(new MatrixVariableMethodArgumentResolver());
		resolvers.add(new MatrixVariableMapMethodArgumentResolver());
		resolvers.add(new ServletModelAttributeMethodProcessor(false));
		resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
		resolvers.add(new RequestHeaderMapMethodArgumentResolver());
		resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
		resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));

		// Type-based argument resolution
		resolvers.add(new ServletRequestMethodArgumentResolver());
		resolvers.add(new ServletResponseMethodArgumentResolver());
		resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RedirectAttributesMethodArgumentResolver());
		resolvers.add(new ModelMethodProcessor());
		resolvers.add(new MapMethodProcessor());
		resolvers.add(new ErrorsMethodArgumentResolver());
		resolvers.add(new SessionStatusMethodArgumentResolver());
		resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

		// Custom arguments
                // 添加自定义解析器
		if (getCustomArgumentResolvers() != null) {
			resolvers.addAll(getCustomArgumentResolvers());
		}

		// Catch-all
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
		resolvers.add(new ServletModelAttributeMethodProcessor(true));

		return resolvers;
	}



感兴趣的话可以这些请求参数的解析方式都看一下,了解一下每一个种类型的解析方式。


回归正题,我们现在集成接口后需要实现两个方法。

supportsParameter 和 resolveArgument,默认自定义的解析器是在最后面。判断supportsParameter支持是否为true,如果为true就走下面resolveArgument方法,

里面返回值就是你需要处理的对象,需要封装你自己的处理逻辑针对注解。

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        HttpSession session = request.getSession();

        UserInfo user = (UserInfo)session.getAttribute(Constant.USER_INFO_SESSION);

        return user;
    }



这样就能通过注解在方法上获取到登录的用户信息。

return-value-handlers的处理方式在spring里面还是有一点不一样。下面会介绍。

© 著作权归作者所有

共有 人打赏支持
上一篇: git日常命令
下一篇: java基础的用法
dxbj1010
粉丝 5
博文 12
码字总数 7474
作品 0
武汉
程序员
私信 提问
spring vmc3.1.1 上,通过AnnotationMethodHandlerAdap...

spring vmc3.1.1 下,通过AnnotationMethodHandlerAdapter配置webBindingInitializer失效解决方案 问题: spring vmc3.1.1 下,通过AnnotationMethodHandlerAdapter配置webBindingInitializ......

爪哇小贩
2013/03/23
0
2
SpringMVC—标签

在Spring3.0中 在Spring3.0.5这个版本上,mvc:annotation-driven/声明是没有 defaultAnnotationHandlerMapping这个属性的,对于@ResultMapping标签的解析,是写死了必须用 "org.springframe...

李长春
2011/09/15
0
0
SpringMVC—标签

在Spring3.0中 在Spring3.0.5这个版本上,mvc:annotation-driven/声明是没有 defaultAnnotationHandlerMapping这个属性的,对于@ResultMapping标签的解析,是写死了必须用 "org.springframe...

李长春
2011/09/15
0
0
springmvc错误java.lang.IllegalArgumentException

jdk1.8+tomcat7.59+eclipseLUNA springmvc.xml 异常 exception root cause

luoyelingluo
2015/05/23
18.6K
3
spring mvc 配置失效了?

版本:spring 3.0以上 项目中有两个spring的配置xml,如下 项目中的web.xml web.xml的配置如下: 1、ContextLoaderListener加载applicationContext-service-database.xml 2、DispatcherServl...

听柳
05/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

对接比特币钱包的PHP开发包

BtcTool是一个基于第三方服务和离线裸交易实现的PHP比特币应用开发包,适合不希望部署本地 节点旳PHP开发者,开发包主要包含以下特性: 利用第三方服务获取指定地址的utxo集合 离线生成消费裸...

汇智网教程
2分钟前
0
0
【自用】 VHD to VHDX

VHDX: 在VHD 2TB 的基础上提供 64TB的容量。 支持逻辑扇区大小为 4KB,和每块的大小为 256MB,来优化虚拟磁盘性能。 比VHD提供更高的安全性、可靠性和性能。 convert-VHD –path d:\Hyper-v...

Tensor丨思悟
14分钟前
0
0
30 岁转行做Python开发晚吗?而且是零基础

最近有小伙伴问小编,30 岁转行做Python开发晚吗? 小编想说,其实无论男女,只要想学,有这个动力,就直接去行动。无论年龄,无论性别,只要你想一直勇往直前,那么想做的就去做吧~这里有一...

糖宝lsh
25分钟前
7
0
详解Spring中的Profile

前言 由于在项目中使用Maven打包部署的时候,经常由于配置参数过多(比如Nginx服务器的信息、ZooKeeper的信息、数据库连接、Redis服务器地址等),导致实际现网的配置参数与测试服务器参数混淆...

watermelon11
40分钟前
4
0
phper必知必会(二)

  1.说说你对进程,线程以及协程的理解      进程:是系统进行资源分配和调度的基本单位,是基本操作系统结构的基础。进程是程序基本执行的实体。进程与进程之间是独立的,拥有完全独立...

SEOwhywhy
56分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部