SpringMVC_HandlerMethodArgumentResolver 实践,实践
HandlerMethodArgumentResolver 是什么?
就是用于解析参数的一个接口,springMVC(4.1)会直接调用这个接口的方法,对参数进行一定的解析。比如会在
InvocableHandlerMethod.getMethodArgumentValues()中调用,并解析方法参数。
具体如图:

然后就会根据这个resolver的规则进行参数的解析。
如何实现?
下面我们可以自定义一个resolver并实现:
具体实现:
1.@CurrentUser

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @
interface CurrentUser {
/**
* 当前用户在request中的名字
*
* @return
*/
String value() default "user"
;
}
View Code
2.CurrentUserMethodArgumentResolver

package com.spring.custom_anno;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
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;
@Component
public class CurrentUserMethodArgumentResolver
implements HandlerMethodArgumentResolver {
public CurrentUserMethodArgumentResolver() {
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.getParameterType().isAssignableFrom(UserBean.
class) && parameter.hasParameterAnnotation(CurrentUser.
class)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory)
throws Exception {
CurrentUser currentUserAnnotation = parameter.getParameterAnnotation(CurrentUser.
class);
//从Session 获取用户
Object object =
webRequest.getAttribute(currentUserAnnotation.value(), NativeWebRequest.SCOPE_SESSION);
//从 accessToken获得用户信息
if (object ==
null) {
String token = webRequest.getHeader("Authorization"
);
if (token ==
null) {
token = webRequest.getParameter("accessToken"
);
}
//为了测试先写死用户名
//TODO: 取真实用户
return new UserBean(1L,"admin"
);
}
return object;
}
}
View Code
3.UserBean

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserBean
implements Serializable {
private Long id;
private String username;
}
View Code
4.Controller

import org.springframework.web.bind.annotation.*
;
@RestController
public class TestController {
@RequestMapping(value = "/testCurrentUser", method = RequestMethod.POST, produces = "application/json", consumes = "application/json"
)
public void test(@CurrentUser UserBean userBean) {
String createdBy =
userBean.getUsername();
System.out.println(createdBy);
}
}
View Code
5.配置
1.(在XML中自定义传统项目做法,注意 自动扫描一定要放在resolver配置的下面才能生效。。实践过)

![]()
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
<!-- 基本包扫描 -->
<context:component-scan base-
package="com.spring" />
<!-- 注册HandlerMapper、HandlerAdapter两个映射类,负责将请求映射到类和方法中 -->
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean
class="com.spring.custom_anno.CurrentUserMethodArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:annotation-driven />
<!-- 访问静态资源,如js, css文件等 -->
<mvc:
default-servlet-handler />
<!-- 视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
View Code
2.(springboot)
只需要在CurrentUserMethodArgumentResolver 类上加上@Component就行了。
用户点评