java封装入参_SpringMVC 中利用RequestMappingHandlerAdapter实现入参和出参的自定义封装...

首先来看下RequestMappingHandlerAdapter这个类的源码

/**

* An {@link AbstractHandlerMethodAdapter} that supports {@link HandlerMethod}s

* with the signature -- method argument and return types, defined in

* {@code @RequestMapping}.

*

*

Support for custom argument and return value types can be added via

* {@link #setCustomArgumentResolvers} and {@link #setCustomReturnValueHandlers}.

* Or alternatively to re-configure all argument and return value types use

* {@link #setArgumentResolvers} and {@link #setReturnValueHandlers(List)}.

*

* @author Rossen Stoyanchev

* @since 3.1

* @see HandlerMethodArgumentResolver

* @see HandlerMethodReturnValueHandler

*/

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter

implements BeanFactoryAware, InitializingBean {

private List customArgumentResolvers;

private HandlerMethodArgumentResolverComposite argumentResolvers;

private HandlerMethodArgumentResolverComposite initBinderArgumentResolvers;

private List customReturnValueHandlers;

private HandlerMethodReturnValueHandlerComposite returnValueHandlers;

private List modelAndViewResolvers;

private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();

private List> messageConverters;

private WebBindingInitializer webBindingInitializer;

private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("MvcAsync");

private Long asyncRequestTimeout;

............................................

从注释中可以了解到通过设置setCustomArgumentResolvers and setCustomReturnValueHandlers可以实现自定义出参和入参的相关规则

由于RequestMappingHandlerAdapter实现了InitializingBean接口所以在初始化的时候会调用afterPropertiesSet()方法

public void afterPropertiesSet() {

if (this.argumentResolvers == null) {

List resolvers = getDefaultArgumentResolvers();

this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);

}

if (this.initBinderArgumentResolvers == null) {

List resolvers = getDefaultInitBinderArgumentResolvers();

this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);

}

if (this.returnValueHandlers == null) {

List handlers = getDefaultReturnValueHandlers();

this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);

}

initControllerAdviceCache();

}

RequestMappingHandlerAdapter方法中有两个方法,getDefaultArgumentResolvers和getDefaultReturnValueHandlers方法,当然我们这边自定义是通过RequestMappingHandlerAdapter的customArgumentResolvers和customReturnValueHandlers属性来实现的,如果通过argumentResolvers和returnValueHandlers属性来直接设置的话,会将spring默认的请求入参和出参覆盖掉

getDefaultArgumentResolvers()方法可以看到我们自定义的入参处理类是被放在中后位置的,同样的getDefaultReturnValueHandlers()方法也是这样

/**

* Return the list of return value handlers to use including built-in and

* custom handlers provided via {@link #setReturnValueHandlers}.

*/

private List getDefaultReturnValueHandlers() {

List handlers = new ArrayList();

// Single-purpose return value types

handlers.add(new ModelAndViewMethodReturnValueHandler());

handlers.add(new ModelMethodProcessor());

handlers.add(new ViewMethodReturnValueHandler());

handlers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.contentNegotiationManager));

handlers.add(new CallableMethodReturnValueHandler());

handlers.add(new DeferredResultMethodReturnValueHandler());

handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));

// Annotation-based return value types

handlers.add(new ModelAttributeMethodProcessor(false));

handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.contentNegotiationManager));

// Multi-purpose return value types

handlers.add(new ViewNameMethodReturnValueHandler());

handlers.add(new MapMethodProcessor());

// Custom return value types

if (getCustomReturnValueHandlers() != null) {

handlers.addAll(getCustomReturnValueHandlers());

}

// Catch-all

if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {

handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));

}

else {

handlers.add(new ModelAttributeMethodProcessor(true));

}

return handlers;

}

此处需要注意的是返回值的处理,由于我们自定义的是处于偏后的位置,如果其他处理类已经返回了,那么我们这边是不会再进入我们自定义的处理类中的

我们可以看到HandlerMethodArgumentResolverComposite 类

public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver {

............................

/**

* Whether the given {@linkplain MethodParameter method parameter} is supported by any registered

* {@link HandlerMethodArgumentResolver}.

*/

public boolean supportsParameter(MethodParameter parameter) {

return getArgumentResolver(parameter) != null;

}

/**

* Iterate over registered {@link HandlerMethodArgumentResolver}s and invoke the one that supports it.

* @exception IllegalStateException if no suitable {@link HandlerMethodArgumentResolver} is found.

*/

public Object resolveArgument(

MethodParameter parameter, ModelAndViewContainer mavContainer,

NativeWebRequest webRequest, WebDataBinderFactory binderFactory)

throws Exception {

HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);

Assert.notNull(resolver, "Unknown parameter type [" + parameter.getParameterType().getName() + "]");

return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);

}

......................................

实现了HandlerMethodArgumentResolver接口

而在其中

/**

* Find a registered {@link HandlerMethodArgumentResolver} that supports the given method parameter.

*/

private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {

HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);

if (result == null) {

for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {

if (logger.isTraceEnabled()) {

logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +

parameter.getGenericParameterType() + "]");

}

if (methodArgumentResolver.supportsParameter(parameter)) {

result = methodArgumentResolver;

this.argumentResolverCache.put(parameter, result);

break;

}

}

}

return result;

}

这里的argumentResolvers就是前文指定添加的

public void afterPropertiesSet() {

if (this.argumentResolvers == null) {

List resolvers = getDefaultArgumentResolvers();

this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);

}

if (this.initBinderArgumentResolvers == null) {

List resolvers = getDefaultInitBinderArgumentResolvers();

this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);

}

if (this.returnValueHandlers == null) {

List handlers = getDefaultReturnValueHandlers();

/*********就是这里************/

this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);

/*********就是这里************/

}

initControllerAdviceCache();

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值