SpringMVC 基于方法参数解析器自定义注入参数方案

一、SpringMVC 基于方法参数解析器自定义注入参数

SpringMVC Web 项目开发中,我们可能需要经常获取一些公共的信息,比如用户信息、请求的 Token 等等,这种情况下我们可以封装一个工具类进行统一获取,也可以通过本篇文章讲解的方法参数解析器进行自动注入。

例如:这里以User 信息和Token为例 ,我们可以以下面这种方式注入到 Controller 层,其中业务开发人员无需关注数据从何而来,直接开箱使用即可:

在这里插入图片描述

下面看下实践的过程:

1. 声明自定义注解

注解中也可以加上一些参数进行更灵活的注入信息。

@Target({
    
    ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
    
    
}
@Target({
    
    ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface User {
    
    
}

2. 声明 User 信息类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
    
    
    private Long id;
    private String userName;
    // 省略其他字段
}

3. 在拦截器中获取相关信息

@Component
@Slf4j
public class UserInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        String token = request.getHeader("token");
        response.setContentType("text/json;charset=utf-8");
        request.setAttribute("CURRENT_USER_INFO", getUserInfo(token));
        request.setAttribute("TOKEN",token);
        return true;
    }

    /**
     * 获取用户信息
     * @param token token
     * @return 用户信息
     */
    private UserInfo getUserInfo(String token){
    
    
        // 查询用户逻辑.....
        // 具体逻辑省略
        // 这里仅演示方法参数解析器效果,先以固定值返回。
        return new UserInfo(1L,"张三");
    }
}

4. 方法参数解析器注入参数

@Component
public class UserAndTokenMethodArgumentResolver implements HandlerMethodArgumentResolver {
    
    

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
    
    
        // 如果参数类型是UserInfo并且有User注解,或者有Token注解则支持
        if ((parameter.getParameterType().isAssignableFrom(UserInfo.class) && parameter.hasParameterAnnotation(User.class))
                || parameter.hasParameterAnnotation(Token.class)) {
    
    
            return true;
        }
        return false;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
    
    
        if (parameter.getParameterType().isAssignableFrom(UserInfo.class) && parameter.hasParameterAnnotation(User.class)) {
    
    
            return webRequest.getAttribute("CURRENT_USER_INFO",
                    RequestAttributes.SCOPE_REQUEST);
        } else if (parameter.hasParameterAnnotation(Token.class)) {
    
    
            return webRequest.getAttribute("TOKEN",
                    RequestAttributes.SCOPE_REQUEST);
        }
        return null;
    }
}

5. 注册拦截器和参数解析器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    
    @Resource
    UserInterceptor userInterceptor;

    @Resource
    UserAndTokenMethodArgumentResolver userAndTokenMethodArgumentResolver;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        registry.addInterceptor(userInterceptor).addPathPatterns("/**");
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
    
    
        resolvers.add(userAndTokenMethodArgumentResolver);
    }
}

6. 使用

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
    
    

    @GetMapping("/test")
    public void test(@User UserInfo user, @Token String token) {
    
    
        log.info("用户信息:{}",user.toString());
        log.info("Token: {}", token);
    }
}

访问测试接口:

在这里插入图片描述

查看日志打印情况:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43692950/article/details/131034527
今日推荐