A brief
Have you ever thought works like @ RequestParam, @ RequestBody these annotations it? Why form form, application / json parameter can be encapsulated directly into the Bean object in it? This comes to HandlerMethodArgumentResolver - method parameter parser, there are two methods of the interface:
public interface HandlerMethodArgumentResolver {
boolean supportsParameter(MethodParameter parameter);
Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception;
}
supportsParameter method returns a boolean value indicating whether to enable the parser, true enable, false to represent not enabled; resolveArgument parsing method represents method parameters, that you to convert HTTP request process parameters for the method parameters, Object returns the object, i.e., the results of the conversion parameters.
@RequestParam corresponding parameter parser is RequestParamMethodArgumentResolver; @RequestBody parameters corresponding parser RequestResponseBodyMethodProcessor; like parser reader can read on their own.
Second, the custom parameter parser
I would like to get the current user's login information, probably follows this effect, just add a comment @CurrentUser, then there will be UserParam parameters currently logged on user information in the method parameter controller.
@RequestMapping(value = "/list", method = RequestMethod.POST)
public ResponseData<List<SysWayDto>> list(@CurrentUser UserParam userParam) {
Map<String, Object> objectMap = MapUtils.convertObjToMap(userParam);
return sysWayService.findWithOriginDest(objectMap);
}
How to achieve it? First, we need to have a @CurrentUser notes:
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}
Then the remaining work is HandlerMethodArgumentResolver things:
@Slf4j
public class CurrentUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
/**
* 用于判定是否需要处理该参数分解,返回 true 为需要,并会去调用下面的方法resolveArgument。
*/
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().isAssignableFrom(UserParam.class)
&& methodParameter.hasParameterAnnotation(CurrentUser.class);
}
/**
* 真正用于处理参数分解的方法,返回的 Object 就是 controller 方法上的形参对象。
*/
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
String accessToken = nativeWebRequest.getHeader(GatewayHeader.accessToken);
try {
UserParam userParam = JsonUtils.readValue(JwtHelper.parseJWT(accessToken), UserParam.class);
return userParam ;
} catch (IOException e) {
log.error("CurrentUserHandlerMethodArgumentResolver resolveArgument readValue error.accessToken:{}", accessToken, e);
} catch (Exception e) {
log.error("CurrentUserHandlerMethodArgumentResolver resolveArgument error.accessToken:{}", accessToken, e);
}
return null;
}
}
Finally, do not forget to register on the custom parameter parser Oh!
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new CurrentUserHandlerMethodArgumentResolver());
}
}