使用过滤器Filter放置参数,减少前端传参示例

2020-11-11 17:50:26 浏览数 (1)

1.功能背景

​ 我们在项目中有些经常会重复使用的参数,如用户信息相关USER_ID。此时并不希望每次都让前端传输重复的参数给我们,一方面减少重复代码的工作量,另一方面可以有效的保护用户隐私信息,这个时候可以在后台将其处理放入过滤器中,实现获得相关的参数的值。

2.示例代码
①包结构
代码语言:javascript复制
├─.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
②POM依赖
代码语言:javascript复制
<?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:

代码语言:javascript复制
/**
 * 用户信息
 */
@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:

代码语言:javascript复制
/**
 * 此处可以改为数据层
 * 为方便展示 暂时只做简单模拟
 */
@Service("userService")
public class UserService {

    public User getUserById(Long id) {
        if (id.equals(1L)) {
            return new User(1L, "张三", 18);
        }
        return null;
    }
}

TestController:

代码语言:javascript复制
@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:

代码语言:javascript复制
/**
 * 通过上下文获取相关类
 */
@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:

代码语言:javascript复制
/**
 * 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:

代码语言:javascript复制
/**
 * 请求的相关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:

代码语言:javascript复制
/**
 * 把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;
    }

}
④测试结果
代码语言:javascript复制
user_id->1 user_name->张三  user_age->18

0 人点赞