自定义参数转换器

方法参数转换器

HandlerMethodArgumentResolver

介绍

使用方法参数转化器[HandlerMethodArgumentResolver]给controller的自定义参数赋值.

使用场景

例:从请求头获取用户信息
现在的方案:获取"SCRM-BASICS"请求头中的数据,然后转换后再获取企业id,自己手动转换,我们可以使用方法参数转换器,自动封装到一个参数中.

@PostMapping("/friends/create")
@ApiOperation(value = "好友助力-创建好友助力活动", notes = "创建好友助力活动")
public BaseResult createFriends(
        @RequestHeader("SCRM-BASICS") String scrm,
        @Valid @RequestBody CreateFriendsReqVO req) throws FriendsHelpException {
    log.info("好友助力-创建好友助力活动请求头信息,userInfo:{},入参:{}", scrm, JSONUtil.toJsonStr(req));
    if (StringUtils.isEmpty(scrm)) {
        throw new FriendsHelpException(NO_LOGIN_ERROR);
    }
    return  helpService.createFriends(new ScrmBasics(scrm).getCorpId(), new ScrmBasics(scrm).getAccountId(), req);
}

替代方案

使用HandlerMethodArgumentResolver

@ApiOperation("新增菜单")
@PostMapping("/add")
public R addMenu(
        @ApiIgnore @CurrentUser CU cu,//我们需要用代码实现,把用户id,自动注入到添加了@CurrentUser注解的CU 类型的cu中
        @Validated(value = {BaseInsert.class}) @RequestBody MenuReqVO req
) {
    log.info("新增菜单,参数:{}", JSONUtil.toJsonStr(req));
    return menuService.add(cu, req);
}

实现步骤

创建一个实体

创建一个实体,用于接收数据

@Data
@AllArgsConstructor
public class CU {

    /**
     * 用户id
     */
    private Long userId;
}



创建一个注解

创建一个注解用于精确定位

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CurrentUser {

}

创建一个转换器

/**
 *该类会在controller的每个方法执行前调用,执行supportsParameter()判断是否转换,调用resolveArgument()转换参数
 */
@Component
@Slf4j
public class CurrentUserResolver implements HandlerMethodArgumentResolver {

    //判断是否进行转化
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        //判断这个方法参数列表中是否具有CU这个类,是否有CurrentUser这个注解
        return parameter.getParameterType().isAssignableFrom(CU.class)
                && parameter.hasParameterAnnotation(CurrentUser.class);
    }


    //具体转换逻辑
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
        //获取请求头的信息,解析出请求信息
        String accessToken = nativeWebRequest.getHeader("accessToken");
        try {
            Claims claims = JwtUtil.parseJWT(accessToken);
            String subject = claims.getSubject();
            LoginUserInfo info = JSONUtil.toBean(subject, LoginUserInfo.class);
            Long userId = info.getUserId();
            //返回要注入的对象            
            return new CU(userId);
        } catch (Exception e) {
            log.warn("token解析异常");
        }
        return null;
    }
}

把转换器注册到spring中

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Autowired
    private CurrentUserResolver currentUserResolver;

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

posted @ 2021-12-29 16:26  宋发准  阅读(99)  评论(0编辑  收藏  举报