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"; }
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; } }
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; }
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); } }
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="ht