By
zhpooer
更新日期:
过滤器概述
Filter, 应用中的保安. 利用过滤器来实现对请求和响应的拦截.
编写过滤器的步骤
编一个类, 实现 javax.servlet.Filter
1
2
3
4
5
6
7
8
9
10
11
12
| public class FilterDemo1 implements javax.servlet.Filter {
public void doFilter(ServletRequest req, ServletResponse, FilterChain chain){
chain.doFilter(req, res);
}
public void init(FilterConfig config){}
public void destroy(){}
}
res.getWriter().write("Hello");
|
配置web.xml,指定哪些资源需要拦截
1
2
3
4
5
6
7
8
9
10
| <filter>
<filter-name>FilterDemo1 </filter-name>
<filter-class>...</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
|
过滤器的执行过程
生命周期
- 应用在加载时会被初始化和初始化
- 针对用户的每次资源访问, 容器都会调用
doFilter
方法
- 应用被卸载或服务器停止时, 会执行
destroy
配置过滤器初始化参数
1
2
3
4
| public init(FilterConfig f){
String value = f.getInitParameter("encoding");
Enumeration en = f.getInitParameterNames();
}
|
1
2
3
4
5
6
| <filter>
<init-param>
<param-name></param-name>
<param-value></param-value>
</init-param>
</filter>
|
过滤器的简单案例
统一字符编码的过滤器
1
2
3
4
5
6
7
8
9
10
11
|
public void doFilter(ServletRequest req, ServletResponse, FilterChain chain){
String encoding = "UTF-8";
String value = filterConfig.getInitParameter("encoding");
if(value!=null){
encoding = "utf-8";
}
req.setCharactorEncoding(encoding);
res.setContentType("text/html;charset=" + encoding);
chain.doFilter(req, res);
}
|
动态资源缓存过滤器(NoCache)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){
HttpServletRequest req;
HttpServletResponse res;
try {
req = (HttpServletRequest) request;
res = (HttpServletRequest) response;
} catch {
throw new RuntimeException("is not a http request");
}
res.setDateHeader("", -1);
res.setHeader("Cache-Control", "no-Cache");
res.setHeader("Pragma", "no-Cache");
chain.doFilter(req, res);
}
|
静态资源缓存过滤器
1
2
3
4
5
| <init-param>
<param-name>css </param-name>
<param-value>1 </param-value>
</init-param>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){
HttpServletRequest req;
HttpServletResponse res;
try {
req = (HttpServletRequest) request;
res = (HttpServletRequest) response;
} catch {
throw new RuntimeException("is not a http reqest");
}
long time = 0;
String uri = res.getRequestURI();
String extendName = uri.subString(uri.lastIndex(".") + 1);
if(html!=null && "html".equals(extendName)){
String value = filterConfig.getInitParameter("css");
time = Long.parse(value*60*60*1000);
}
res.setDateHeader("Expires", System.currentTimeMillis()+time);
chain.doFilter(req, res);
}
|
自动登陆过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){
HttpServletRequest req;
HttpServletResponse res;
try {
req = (HttpServletRequest) request;
res = (HttpServletRequest) response;
} catch {
throw new RuntimeException("is not a http reqest");
}
HttpSession session = req.getSession();
User user = (User)session.getAttribute("user");
if(user==null){
Cookie[] cs = req.getCookies();
for(c <- cs if "loginInfo".equals(c.getName()){
String username = c.getValue().split("\\_")[0];
String password = c.getValue().split("\\_")[1];
if(password==password){
User u = new User();
u.setUsername(username);
u.setPassword(password);
req.getSession().setAttribute("user", u);
}
break;
}
}
chain.doFilter(req, res);
}
|
用户密码加密
1
2
3
4
5
6
7
8
| public static String md5(String s){
MessageDigest md = MessageDigest.getInstance("md5");
byte b[] = md.digest(s.getBytes());
Base64Encoder en = new Base64Encoder();
return en.encode(b)
}
new Base64Encoder().encode(s.getBytes());
|
过滤器的高级配置
1
2
3
4
5
6
7
8
| <filter-mapping>
<dispatcher> REQUEST </dispatcher>
<dispatcher> FORWARD </dispatcher>
<dispatcher> INCLUDE </dispatcher>
<dispatcher> ERROR </dispatcher>
</filter-mapping>
|
注:
- page指令, errorPage="*.jsp", 属于转发方式
- web.xml 配置的全局错误提示页面, 是的状态是 ERROR
过滤器的高级案例
全站中文乱码解决过滤器
请求: Post Get参数乱码; 响应输出乱码解决过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| public void doFilter(){
HttpServletRequest req;
HttpServletResponse res;
try {
req = (HttpServletRequest) request;
res = (HttpServletRequest) response;
} catch {
throw new RuntimeException("is not a http reqest");
}
String encoding = "utf-8";
String value = filtercofnig.getInitParameter("encoding");
if(value!=null){
encoding = value;
}
req.setCharactorEncoding(encoding);
res.setCharactorEncoding(encoding);
res.setContentType("text/html;charset=" + encoding);
MyHttpServletRequest mrequest = new MyHttpServletRequest(request);
chain.doFilter(mrequest, res);
}
class MyHttpServletRequest extends HttpServletRequestWrapper {
public MyHttpServletRequest(HttpServletRequest req){
super(req);
}
@Override public String getParameter(String name) {
String value = super.getParameter(name);
if(value==null){
return null;
}
String method = super.getMethod();
if("get".equalsIgnoreCase(method)) {
value = new String(value.getBytes("iso-8859-1"), super.getCharactorEncoding());
}
return value;
}
}
|
脏话过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public void doFilter(){
HttpServletRequest req;
HttpServletResponse res;
try {
req = (HttpServletRequest) request;
res = (HttpServletRequest) response;
} catch {
throw new RuntimeException("is not a http reqest");
}
DirtyWordsHttpServletRequest dwrequest = new DirtyWordsHttpServletRequest(req);
chain.doFilter(dwrequest, res);
}
class DirtyWordsHttpServletRequest extends HttpServletRequestWrapper{
private String dwords[] = {"xx", "xxx"};
public String getParameter(String name){
String value = super.getParameter(name);
if(value==null) return null;
for(String s : dwords){
value = value.replace(s, "*")
}
return value;
}
}
|
HTML标记过滤器
<
换成<
, 可以防止代码注入
1
2
3
4
5
6
7
8
9
| class HtmlHttpServletRequest extends HttpServletRequestWrapper{
private String dwords[] = {"xx", "xxx"};
public String getParameter(String name){
String value = super.getParameter(name);
if(value==null) return null;
value = filter(value);
return value;
}
}
|
全站 GZIP 压缩过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| public void doFilter(){
HttpServletRequest req;
HttpServletResponse res;
try {
req = (HttpServletRequest) request;
res = (HttpServletRequest) response;
} catch {
throw new RuntimeException("is not a http reqest");
}
GZIPHttpResponse ghp = new GZIPHttpResponse(res);
chain.doFilter(req, ghp);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream();
gout.write(ghp.getBytes());
gout.close();
Byte[] ba = bo.toByteArray();
res.setHeader("Content-Encoding", "gzip");
res.setContentLength(o.length);
res.getOutputStream().write(ba);
}
public class GZIPHttpResponse extends HttpServletResponseWrapper{
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private PrintWriter pw = null;
@Override public ServletOutPutStream getOutputStream(){
return new GZIPOutputStream(baos);
}
@Override public PrintWriter getWriter(){
pw = new PrintWriter(new OutputStreamWriter(baos, super.getCharactorEncoding()));
return pw;
}
public Byte[] getBytes(){
if(pw!=null) pw.flush();
baos.flush();
baos.getBytes();
}
}
class GZIPServletOupStream extends ServletOutPutStream {
private ByteArrayOutputStream baos;
public GZIPServletOupStream( ByteArrayOutputStream baos ){
this.baos = baos;
}
public void write(int b) {
baos.write(b);
}
}
|
显示数据用的静态资源需要压缩, 还有JSP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <filter-mapping>
<filter-name> GZIPFilter </filter-name>
<url-pattern> *.jsp </url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name> GZIPFilter </filter-name>
<url-pattern> *.css </url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name> GZIPFilter </filter-name>
<url-pattern> *.js </url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name> GZIPFilter </filter-name>
<url-pattern> *.html </url-pattern>
</filter-mapping>
|