欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringBoot集成自定义HandlerMethodArgumentResolver参数初始值解析

程序员文章站 2022-04-01 19:59:01
...

大部分摘抄自https://www.cnblogs.com/yangzhilong/p/7605889.html

传统SpringMVC集成自定义HandlerMethodArgumentResolver的方式为:http://www.cnblogs.com/yangzhilong/p/6282218.html

在SpringBoot中是去配置文件化的,具体做法有:

1、启动类继承WebMvcConfigurerAdapter

2、另外写一个@Configuration注解的来继承WebMvcConfigurerAdapter(推荐)

import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.longge.LoginUserInfoMethodArgumentResolver;

@SpringBootApplication
public class MyBootApplication extends WebMvcConfigurerAdapter{
    public static void main(String[] args) {
        SpringApplication.run(MyBootApplication.class, args);
    }
    
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        super.addArgumentResolvers(argumentResolvers);
        argumentResolvers.add(new LoginUserInfoMethodArgumentResolver());
    }
}

 

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.longge.utils.Constant;
import com.longge.utils.RedisCacheUtils;

/**
 * 获取用户的session dto
 */
public class LoginUserInfoMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public Object resolveArgument(MethodParameter arg0, ModelAndViewContainer arg1, NativeWebRequest arg2,
            WebDataBinderFactory arg3) throws Exception {
        String token = arg2.getHeader(Constant.TOKEN_KEY);
        if(StringUtils.isNotBlank(token)) {
            return RedisCacheUtils.getUserInfo(token);
        }
        return null;
    }

    @Override
    public boolean supportsParameter(MethodParameter arg0) {
        return arg0.getParameterType().equals(UserInfo.class);
    }

}

 使用方法:

@ApiOperation("新增")
@PutMapping("add")
public ResponseResult<SupplierDto> add(UserInfo userInfo, @Valid @RequestBody SupplierDto supplierDto) {
    // 这里的UserInfo不需要加任何注解,因为LoginUserInfoMethodArgumentResolver是对class的类型来解析的
}

 上面是直接使用class类的方式,接下来使用注解的方式来实现

import java.lang.annotation.*;

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

}

 

import com.chinamobile.annation.CurrentUser;
import com.chinamobile.dto.CurrentUserData;
import com.chinamobile.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;


public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private RedisUtil redisUtil;

    public CurrentUserMethodArgumentResolver() {
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(CurrentUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String accessToken = webRequest.getHeader("authorization");
        if (StringUtils.isEmpty(accessToken)) {
            return null;
        }

        Object object = redisUtil.get(accessToken);
        if (object instanceof CurrentUserData) {
            return object;
        }
        return null;
    }
}

 这里的RedisUtil是一个redis的处理类,自行实现就是。

import com.CurrentUserMethodArgumentResolver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

@Configuration
@Slf4j
public class ApiConfig extends WebMvcConfigurerAdapter {

    /**
     * 注册解析器bean
     *
     * @return
     */
    @Bean
    public CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver() {
        return new CurrentUserMethodArgumentResolver();
    }

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

}

 使用如下:

/**
     * 修改用户信息
     *
     * @param userId
     * @param addUserModel
     * @param currentUserData
     * @return
     */
    @PutMapping(value = "/users/{userId}")
    public CommonResponse<String> updateUser(@PathVariable("userId") Integer userId,
                                             @RequestBody AddUserModel addUserModel, 
                                             @CurrentUser CurrentUserData currentUserData) {

        CommonResponse<String> commonResponse = new CommonResponse<>();
        try {
            Integer updateBy = currentUserData.getUserId();
            // 参数校验
            if (userId == null) {
                commonResponse.setCode(ResponseCode.PARAMETER_ERROR);
                commonResponse.setMsg("参数校验未通过,请检查参数合法性");
                log.info("Parameter check failed.");
            }else {
                commonResponse.setCode(ResponseCode.SUCCESS);
                commonResponse.setMsg("修改用户成功.");
                log.info("Update user info success.");
            }
        } catch (Exception ex) {
            log.error("SERVER_ERROR: " + ex);
            commonResponse.setCode(ResponseCode.SERVER_ERROR);
            commonResponse.setMsg("SERVER_ERROR");
        }
        return commonResponse;
    }