猿问

HandlerMethodArgumentResolver的原理是什么?

如题:在一个controller的请求方法中,有两个自定义的参数注解@UserInfo和@SchoolInfo

@RequestMapping(value = "/filter/test2")
    public String test2(@RequestBody String o, @UserInfo UserInfoVo userInfoVo, @SchoolInfo SchoolInfoVo schoolInfoVo) {
        System.out.println("Controller中获取的请求数据:" + o);
        System.out.println("自定义注解UserInfo的值:" + userInfoVo);
        System.out.println("自定义注解SchoolInfo的值:" + schoolInfoVo);
        return "OK";
    }

实现两个参数解析器如下:

public class LoginUserInfoMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
//        return parameter.getParameterType().equals(UserInfoVo.class);
        System.out.println("login" + parameter.hasParameterAnnotation(UserInfo.class));
        return parameter.hasParameterAnnotation(UserInfo.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest httpServletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        String str = HttpHelper.getBodyString(httpServletRequest);
        System.out.println("参数解析器login获取的请求数据:" + str);
        UserInfoVo u = new UserInfoVo();
        u.setName("洪桓");
        u.setAge(233);
        return u;
    }
}
public class SchoolInfoMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        System.out.println("school" + parameter.hasParameterAnnotation(SchoolInfo.class));
        return parameter.hasParameterAnnotation(SchoolInfo.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest httpServletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        String str = HttpHelper.getBodyString(httpServletRequest);
        System.out.println("参数解析器school获取的请求数据:" + str);
        SchoolInfoVo schoolInfoVo = new SchoolInfoVo();
        schoolInfoVo.setName("HNU");
        schoolInfoVo.setYear(1980);
        return schoolInfoVo;
    }
}

WebMvcConfigurerAdapter中实现顺序如下:

@Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        super.addArgumentResolvers(argumentResolvers);
        argumentResolvers.add(new LoginUserInfoMethodArgumentResolver());
        argumentResolvers.add(new SchoolInfoMethodArgumentResolver());
    }

最后输出结果

logintrue
loginfalse
schooltrue

如果按照list的添加顺序算的话,第一遍扫描判断parameter.hasParameterAnnotation(UserInfo.class)是true,第二遍扫描parameter.hasParameterAnnotation(UserInfo.class)和parameter.hasParameterAnnotation(SchoolInfo.class)分别是flase和true,为什么第二次参数解析器中会返回false

Qyouu
浏览 1350回答 1
1回答

墨色风雨

第一次是传 @UserInfo UserInfoVo userInfoVo 进去,所以是true 第二次是传 @SchoolInfo SchoolInfoVo schoolInfoVo 进去,所以是false,然后遍历到 SchoolInfoMethodArgumentResolver 返回true了
随时随地看视频慕课网APP

相关分类

Java
我要回答