SpringMVC custom parameter parser

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());
    }
}

Guess you like

Origin www.cnblogs.com/jmcui/p/11909524.html