Spring Boot 学习笔记(八) 整合 Filter
- Spring Boot 学习笔记 源码地址
- Spring Boot 学习笔记(一) hello world
- Spring Boot 学习笔记(二) 整合 log4j2
- Spring Boot 学习笔记(三) 整合 MyBatis + Druid
- Spring Boot 学习笔记(四) 整合 Druid 监控
- Spring Boot 学习笔记(五) 整合 静态资源
- Spring Boot 学习笔记(六) 整合 RESTful 参数传递
- Spring Boot 学习笔记(七) 整合 Swagger2
- Spring Boot 学习笔记(八) 整合 Filter
Spring Boot 学习笔记(八) 整合 Filter
1. 创建自定义的 Filter
创建一个 DemoFilter
1package com.zdran.springboot.filter;
2
3import org.slf4j.Logger;
4import org.slf4j.LoggerFactory;
5
6import javax.servlet.*;
7import java.io.IOException;
8
9/**
10 * Create by ranzd on 2018/8/9
11 *
12 * @author cm.zdran@gmail.com
13 */
14public class DemoFilter implements Filter{
15 private Logger logger = LoggerFactory.getLogger(DemoFilter.class);
16 @Override
17 public void init(FilterConfig filterConfig) throws ServletException {
18 logger.info("初始化 DemoFilter ");
19 }
20
21 @Override
22 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
23 throws IOException, ServletException {
24 logger.info("拦截到参数:{}", servletRequest.getParameterMap());
25 if (true) {
26 filterChain.doFilter(servletRequest,servletResponse);
27 }
28 logger.info("拦截到参数。请求被拦截");
29 }
30
31 @Override
32 public void destroy() {
33 logger.info("销毁 DemoFilter ");
34 }
35}
36
核心的方法是 doFilter,可以在这个方法内对参数进行校验,通过servletRequest可以获取到请求中的参数。根据参数进行拦截。
1filterChain.doFilter(servletRequest,servletResponse);
如果调用了这行代码说明不拦截这次请求,如果没有调用这行代码,这次请求请求将被拦截。
2. 初始化 Filter
将这个Filter注入到容器中,创建 FilterConfig 类
1@Configuration
2public class FilterConfig {
3 private Logger logger = LoggerFactory.getLogger(FilterConfig.class);
4 @Bean
5 public FilterRegistrationBean xssFilterRegistrationBean() {
6 logger.info("初始化 DemoFilter 过滤器 Bean");
7 FilterRegistrationBean<Filter> initXssFilterBean = new FilterRegistrationBean<>();
8 initXssFilterBean.setFilter(new DemoFilter());
9 initXssFilterBean.setOrder(1);
10 initXssFilterBean.setEnabled(true);
11 initXssFilterBean.addUrlPatterns("/*");
12 initXssFilterBean.setDispatcherTypes(DispatcherType.REQUEST);
13 return initXssFilterBean;
14 }
15}
setOrder方法可以对这个 Filter 设置一个优先级,这个值越小,越先被执行。尽量不要与其他的 Filter 冲突
3. HttpServletRequestWrapper 修改参数
有些时候我们可能需要对参数进行修改,比如XSS过滤,防SQL注入等。这个时候我们可以通过HttpServletRequestWrapper 来对参数进行修改。 创建 DemoHttpServletRequestWrapper。通过重写这个类的一些方法来对参数进行修改。
1package com.zdran.springboot.filter;
2
3import org.slf4j.Logger;
4import org.slf4j.LoggerFactory;
5
6import javax.servlet.ReadListener;
7import javax.servlet.ServletInputStream;
8import javax.servlet.http.HttpServletRequest;
9import javax.servlet.http.HttpServletRequestWrapper;
10import javax.servlet.http.HttpSession;
11import java.io.*;
12import java.util.Map;
13
14/**
15 * Create by ranzd on 2018/8/9
16 *
17 * @author cm.zdran@gmail.com
18 */
19public class DemoHttpServletRequestWrapper extends HttpServletRequestWrapper {
20
21 private Logger logger = LoggerFactory.getLogger(DemoHttpServletRequestWrapper.class);
22
23 public DemoHttpServletRequestWrapper(HttpServletRequest request) {
24 super(request);
25 }
26
27 @Override
28 public String getHeader(String name) {
29 String value = super.getHeader(name);
30 logger.info("获取 Header 中的参数:{}", value);
31 return value;
32 }
33
34 @Override
35 public String getParameter(String name) {
36 String value = super.getParameter(name);
37 logger.info("获取 getParameter 中的参数:{}", value);
38 return value;
39 }
40
41 @Override
42 public Map<String, String[]> getParameterMap() {
43 Map<String, String[]> map = super.getParameterMap();
44 logger.info("获取 getParameterMap 中的参数:{}", map);
45 return map;
46 }
47
48 @Override
49 public HttpSession getSession() {
50 HttpSession session = super.getSession();
51 logger.info("获取 getCookies 中的cookie:{}", session);
52 return session;
53 }
54
55 @Override
56 public Object getAttribute(String name) {
57 Object obj = super.getAttribute(name);
58 logger.info("获取 getCookies 中的cookie:{}", obj);
59
60 return obj;
61 }
62
63 @Override
64 public String[] getParameterValues(String name) {
65 String[] value = super.getParameterValues(name);
66 logger.info("获取 getParameter 中的参数:{}", value);
67 return value;
68 }
69
70 @Override
71 public ServletInputStream getInputStream() throws IOException {
72 BufferedReader br = new BufferedReader(new InputStreamReader(super.getInputStream()));
73 StringBuilder resultBuilder = new StringBuilder();
74 String line;
75 while ((line = br.readLine()) != null) {
76 resultBuilder.append(line);
77 }
78 String result = resultBuilder.79 [native code]
80}">toString();
81 logger.info("获取 getInputStream 中的参数:{}", result);
82 return new WrappedServletInputStream(new ByteArrayInputStream(result.getBytes()));
83 }
84
85 /**
86 * 读取 RequestBody 中的参数时需要重新再次写入到流中,
87 * 否则在 Controller 中会读取不到参数。
88 */
89 private class WrappedServletInputStream extends ServletInputStream {
90 public void setStream(InputStream stream) {
91 this.stream = stream;
92 }
93
94 private InputStream stream;
95
96 public WrappedServletInputStream(InputStream stream) {
97 this.stream = stream;
98 }
99
100 @Override
101 public int read() throws IOException {
102 return stream.read();
103 }
104
105 @Override
106 public boolean isFinished() {
107 return true;
108 }
109
110 @Override
111 public boolean isReady() {
112 return true;
113 }
114
115 @Override
116 public void setReadListener(ReadListener readListener) {
117
118 }
119 }
120}
121
注意: 在读取 RequestBody中的参数的时候需要用 getInputStream 方法,而且读取结束后,必须再次向该流中写入,否则Controller将读取不到参数。
转载请注明出处
本文链接:zdran.com/20180809.ht…