1. 应用场景
从token解析出来的信息想放到controller层的参数对象中。此处用到java反射,不会的自行学习。
2. 代码
创建Spring boot项目
创建@Zkq注解
import java.lang.annotation.*;
/**
* @Description 自定义参数解析器注解
* @Author 张凯强
* @Date Created in 2021/5/19
* @E-mail 862166318@qq.com
*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Zkq {}
创建参数解析器
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import java.lang.reflect.Field;
/**
* @Description 参数解析器,利用反射创建对象并从nativeWebRequest取出我们在filter中的值
* @Author 张凯强
* @Date Created in 2021/5/19
* @E-mail 862166318@qq.com
*/
public class ZkqParameterHandler implements HandlerMethodArgumentResolver {
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(Zkq.class);
}
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
// 得到反射对象的类
Class<?> nestedParameterType = methodParameter.getNestedParameterType();
// 利用反射创建当前注解的实体类
Object o = nestedParameterType.getConstructor().newInstance();
// 利用反射获取当前类的所有私有属性
Field[] fields = nestedParameterType.getDeclaredFields();
// 利用反射给创建的类赋值
for (Field field:fields) {
// 开启私有属性的赋值功能
field.setAccessible(true);
field.set(o,nativeWebRequest.getAttribute(field.getName(), RequestAttributes.SCOPE_REQUEST));
}
return o;
}
}
把解析器添加到Spring 容器中
import org.springframework.boot.web.servlet.FilterRegistrationBean;
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.WebMvcConfigurer;
import java.util.List;
/**
* @Description 接口WebMvcConfigurer 添加参数解析器
* @Author 张凯强
* @Date Created in 2021/5/19
* @E-mail 862166318@qq.com
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
// 添加参数解析器
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new ZkqParameterHandler());
}
// 添加 filter 向servletRequest 中放值,这里我写死的,可以从token或数据库中那动态数据
@Bean
public FilterRegistrationBean zkqFilter(){
return new FilterRegistrationBean((servletRequest,servletResponse,filterChain) ->{
servletRequest.setAttribute("id",1L);
servletRequest.setAttribute("name","张凯强");
servletRequest.setAttribute("age",25);
servletRequest.setAttribute("sex","男");
servletRequest.setAttribute("email","862166318@qq.com");
filterChain.doFilter(servletRequest,servletResponse);
}){{
setOrder(1);
setName("zkq");
setEnabled(true);
addUrlPatterns("/*");
}};
}
}
3. 测试代码
创建实体类User
import lombok.Data;
/**
* @Description 用户信息
* @Author 张凯强
* @Date Created in 2021/5/19
* @E-mail 862166318@qq.com
*/
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String sex;
private String email;
}
创建测试Controller API接口
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description test
* @Author 张凯强
* @Date Created in 2021/5/19
* @E-mail 862166318@qq.com
*/
@RestController
public class ZkqController {
@RequestMapping("zkq")
public User zkq(@Zkq User user){
return user;
}
}
启动项目
4. 测试结果
访问地址:http://localhost:8080/zkq
成功结果
demo下载
有问题质询QQ:248048521,欢迎技术交流