文档章节

spring的annotation-driven

dxbj1010
 dxbj1010
发布于 2016/05/09 21:16
字数 734
阅读 66
收藏 3
点赞 2
评论 0

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里面还是有一点不一样。下面会介绍。

© 著作权归作者所有

共有 人打赏支持
dxbj1010
粉丝 4
博文 11
码字总数 7474
作品 0
武汉
程序员
spring mvc 配置失效了?

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

听柳 ⋅ 05/31 ⋅ 0

Spring 3 MVC and JSR303 @Valid example

In Spring 3, you can enable “mvc:annotation-driven” to support JSR303 bean validation via annotation, if any JSR 303 validator framework on the classpath. Note Hibernate Vali......

凯文加内特 ⋅ 2015/10/10 ⋅ 0

mybatis的xml配置和注解配置

xml配置 spring-application.xml spring-annotation-componentScan.xml spring-data.xml spring-mybatis.xml spring-transaction.xml 测试 注意: MapperScannerConfigurer 实现了BeanDefin......

乾坤刀 ⋅ 05/31 ⋅ 0

<mvc:annotation-driven >和context:component-scan的区别 为啥要说这两个注解的区别,因为<mvc:annotation-driven >和context:component-scan放置的位置出错,可能就会导致项目出现404的错误......

小车车 ⋅ 2016/07/07 ⋅ 0

Spring与SpringMVC的容器关系分析

Spring与SpringMVC的容器关系分析 结论: Spring(springContext.xml)容器配置,排除所有@controller 的Bean <context:component-scan base-package="com.service,com.util,com.dao" > Spri......

LYQ1990 ⋅ 2016/05/24 ⋅ 0

SpringMVC配置全局日期转换器,处理日期转换异常

spring3.0配置日期转换可以通过配置自定义实现WebBingingInitializer接口的一个日期转换类来实现,方法如下 转换类: public class DateConverter implements WebBindingInitializer { publ...

Zero零_度 ⋅ 2016/03/14 ⋅ 0

解决SpringMVC的@ResponseBody返回中文乱码

SpringMVC的@ResponseBody返回中文乱码的原因是SpringMVC默认处理的字符集是ISO-8859-1,在Spring的org.springframework.http.converter.StringHttpMessageConverter类中可以看到如下代码: ...

爱笑的痴迷者 ⋅ 2016/09/21 ⋅ 0

spring mvc访问静态文件(css/js/img)访问不到

web.xml中配置: <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-st......

凯哥java ⋅ 2016/11/04 ⋅ 0

SpringMVC—标签

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

李长春 ⋅ 2011/09/15 ⋅ 0

SpringMVC—标签

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

李长春 ⋅ 2011/09/15 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

在树莓派上搭建一个maven仓库

在树莓派上搭建一个maven仓库 20180618 lambo init 项目说明 家里有台树莓派性能太慢。想搭建一个maven私服, 使用nexus或者 jfrog-artifactory 运行的够呛。怎么办呢,手写一个吧.所在这个...

林小宝 ⋅ 15分钟前 ⋅ 0

Spring发展历程总结

转自与 https://www.cnblogs.com/RunForLove/p/4641672.html 目前很多公司的架构,从Struts2迁移到了SpringMVC。你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢?...

onedotdot ⋅ 47分钟前 ⋅ 0

Python模块/包/库安装(6种方法)

Python模块/包/库安装(6种方法) 冰颖机器人 2016-11-29 21:33:26 一、方法1: 单文件模块 直接把文件拷贝到 $python_dir/Lib 二、方法2: 多文件模块,带setup.py 下载模块包(压缩文件zip...

cswangyx ⋅ 今天 ⋅ 0

零基础学习大数据人工智能,学习路线篇!系统规划大数据之路?

大数据处理技术怎么学习呢?首先我们要学习Python语言和Linux操作系统,这两个是学习大数据的基础,学习的顺序不分前后。 Python:Python 的排名从去年开始就借助人工智能持续上升,现在它已经...

董黎明 ⋅ 今天 ⋅ 0

openJdk和sun jdk的区别

使用过LINUX的人都应该知道,在大多数LINUX发行版本里,内置或者通过软件源安装JDK的话,都是安装的OpenJDK, 那么到底什么是OpenJDK,它与SUN JDK有什么关系和区别呢? 历史上的原因是,Ope...

jason_kiss ⋅ 今天 ⋅ 0

梳理

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 它是JS的状态容器,是一种解决问题的方式,所以即可以用于 react 也可以用于 vue。 需要理解其思想及实现方式。 应用中所有的 stat...

分秒 ⋅ 今天 ⋅ 0

Java 后台判断是否为ajax请求

/** * 是否是Ajax请求 * @param request * @return */public static boolean isAjax(ServletRequest request){return "XMLHttpRequest".equalsIgnoreCase(((HttpServletReques......

JavaSon712 ⋅ 今天 ⋅ 0

Redis 单线程 为何却需要事务处理并发问题

Redis是单线程处理,也就是命令会顺序执行。那么为什么会存在并发问题呢? 个人理解是,虽然redis是单线程,但是可以同时有多个客户端访问,每个客户端会有 一个线程。客户端访问之间存在竞争...

码代码的小司机 ⋅ 今天 ⋅ 0

到底会改名吗?微软GVFS 改名之争

微软去年透露了 Git Virtual File System(GVFS)项目,GVFS 是 Git 版本控制系统的一个开源插件,允许 Git 处理 TB 规模的代码库,比如 270 GB 的 Windows 代码库。该项目公布之初就引发了争...

linux-tao ⋅ 今天 ⋅ 0

笔试题之Java基础部分【简】【二】

1.静态变量和实例变量的区别 在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变...

anlve ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部