我们在项目中有些经常会重复使用的参数,如用户信息相关USER_ID。此事并不希望每次都让前端传输重复的参数给我们,一方面减少重复代码的工作量,另一方面可以有效的保护用户隐私信息,这个时候可以在后台将其处理放入过滤器中,实现获得相关的参数的值。
├─.idea │ ├─codeStyles │ ├─dictionaries │ ├─inspectionProfiles │ └─libraries ├─.mvn │ └─wrapper ├─src │ ├─main │ │ ├─java │ │ │ └─com │ │ │ └─example │ │ │ └─demo │ │ │ ├─config │ │ │ ├─context │ │ │ ├─controller │ │ │ ├─entity │ │ │ └─service │ │ └─resources │ └─test │ └─java │ └─com │ └─example │ └─demo └─target ├─classes │ └─com │ └─example │ └─demo │ ├─config │ ├─context │ ├─controller │ ├─entity │ └─service ├─generated-sources │ └─annotations ├─generated-test-sources │ └─test-annotations └─test-classes └─com └─example └─demo 复制代码
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- ################## Lombok ################## --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.0</version><!--$NO-MVN-MAN-VER$ --> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.5</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 复制代码
User:
/** * 用户信息 */ @Data @NoArgsConstructor @AllArgsConstructor public class User { private Long id; private String name; private int age; public User(Long id, String name, int age) { this.id = id; this.name = name; this.age = age; } /** * 创建时间 */ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date createTime; } 复制代码
UserService:
/** * 此处可以改为数据层 * 为方便展示 暂时只做简单模拟 */ @Service("userService") public class UserService { public User getUserById(Long id) { if (id.equals(1L)) { return new User(1L, "张三", 18); } return null; } } 复制代码
TestController:
@Slf4j @RestController @RequestMapping public class TestController { @RequestMapping("/") public String test(Long user_id, String user_name, Integer user_age) { String params = "user_id->" + user_id + " user_name->" + user_name + " user_age->" + user_age; return params; } } 复制代码
BaseApplicationContext:
/** * 通过上下文获取相关类 */ @Configuration public class BaseApplicationContext implements ApplicationContextAware { private static ApplicationContext applicationContext = null; @Override public void setApplicationContext(ApplicationContext context) throws BeansException { applicationContext = context; } /** * 获取applicationContext对象 * * @return applicationContext对象 */ public static ApplicationContext getApplicationContext() { return applicationContext; } /** * 根据bean的id来查找对象 * * @param id beanId * @return 根据id查找到的对象 */ public static <T> T getBeanById(String id) { return (T) applicationContext.getBean(id); } /** * 根据bean的id来查找对象 * * @param id beanId * @param clazz 类型 * @return 根据id查找到的对象 */ public static <T> T getBeanById(String id, Class<T> clazz) { return applicationContext.getBean(id, clazz); } /** * 根据bean的class来查找对象 * * @param c class * @return bean的class查找到的对象 */ public static <T> T getBeanByClass(Class<T> c) { return (T) applicationContext.getBean(c); } /** * 根据bean的class来查找所有的对象(包括子类) * * @param c * @return */ public static Map getBeansByClass(Class c) { return applicationContext.getBeansOfType(c); } public static String getMessage(String key) { return applicationContext.getMessage(key, null, Locale.getDefault()); } } 复制代码
RequestWrapper:
/** * HttpServletRequest的包装类 */ public class RequestWrapper extends HttpServletRequestWrapper { private Map<String, String[]> userInfoMap = new HashMap<String, String[]>(); /** * 特殊的参数名称列表 */ private static final Set<String> SPECIAL_NAME = new HashSet<String>(); /** * 当前操作的店铺 */ public static final String user_id = "user_id".toLowerCase(); public static final String user_name = "user_name".toLowerCase(); public static final String user_age = "user_age".toLowerCase(); static { SPECIAL_NAME.add(user_id.toLowerCase()); SPECIAL_NAME.add(user_name.toLowerCase()); SPECIAL_NAME.add(user_age.toLowerCase()); } private final HttpServletResponse response; public RequestWrapper(HttpServletRequest request, HttpServletResponse response) { super(request); this.response = response; UserService userService = BaseApplicationContext.getBeanById("userService", UserService.class); User user = userService.getUserById(1L); userInfoMap.put(user_id, this.toArray(user.getId().toString())); userInfoMap.put(user_name, this.toArray(user.getName())); userInfoMap.put(user_age, this.toArray(String.valueOf(user.getAge()))); } @Override public String getParameter(String name) { String[] values = this.getParameterValues(name); if (values == null) { return null; } else { return values[0]; } } @Override public String[] getParameterValues(String name) {// NOPMD String lowerCaseName = StringUtils.lowerCase(name); if (SPECIAL_NAME.contains(lowerCaseName)) { return userInfoMap.get(lowerCaseName); } else { return super.getParameterValues(name); } } private String[] toArray(String content) { if (content == null) { return null; } else { return new String[]{content}; } } } 复制代码
UserInfoRequestWrapperFilter:
/** * 请求的相关Filter */ @Slf4j public class UserInfoRequestWrapperFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; RequestWrapper httpRequestWraper = new RequestWrapper(request, response); chain.doFilter(httpRequestWraper, res); } @Override public void destroy() { log.info(" UserInfoRequestWrapperFilter destory "); } @Override public void init(FilterConfig filterConfig) throws ServletException { log.info(" init UserInfoRequestWrapperFilter "); } } 复制代码
FilterConfiguration:
/** * 把Filter注册到SpringBoot中 */ @Configuration public class FilterConfiguration { @Bean public FilterRegistrationBean<UserInfoRequestWrapperFilter> grantFilterFilter(){ FilterRegistrationBean<UserInfoRequestWrapperFilter> filterRegistrationBean = new FilterRegistrationBean<>(); UserInfoRequestWrapperFilter userInfoRequestWrapperFilter = new UserInfoRequestWrapperFilter(); filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico"); filterRegistrationBean.setFilter(userInfoRequestWrapperFilter); filterRegistrationBean.setOrder(2); filterRegistrationBean.setEnabled(true); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.setName("userInfoRequestWrapperFilter"); return filterRegistrationBean; } } 复制代码
user_id->1 user_name->张三 user_age->18 复制代码