Web笔记-Filter

1. 利用过滤器解决全站编码问题:
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
package cn.imeina.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SetCharacterEncodingFilter implements Filter {
/**
* web.xml中该过滤器的配置参数
*/
private FilterConfig fConfig;
public SetCharacterEncodingFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
//FilterConfig获取配置参数
String encoding = fConfig.getInitParameter("encoding");
if (encoding == null) {
encoding = "UTF-8";
}
request.setCharacterEncoding(encoding);
//更改字符流输出时的编码为UTF-8
response.setCharacterEncoding(encoding);
//更改字符流输出时的编码为UTF-8,同时通知浏览器以UTF-8编码显示
response.setContentType("text/html;charset=" + encoding);
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
this.fConfig = fConfig;
}
}

web.xml中配置

1
2
3
4
5
6
7
8
9
10
11
12
13
<filter>
<filter-name>SetCharacterEncodingFilter</filter-name>
<filter-class>com.gaoshiyi.web.filter.SetCharacterEncodingFilter</filter-class>
<!-- 过滤器添加配置参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SetCharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


2. 控制动态资源禁止缓存过滤器
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
package cn.imeina.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DynamicResourceNoCacheFilter implements Filter {
public DynamicResourceNoCacheFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//该段代码可以在HttpServlet源码中service方法中找到...
HttpServletRequest req;
HttpServletResponse resp;
try {
req = (HttpServletRequest) request;
resp = (HttpServletResponse) response;
} catch (Exception e) {
throw new RuntimeException("non-http request or response");
}
//设置控制禁止缓存的三个响应头
resp.setHeader("Expries", "-1");//HTTP1.0和1.1都有
resp.setHeader("Cache-Control", "no-cache");//HTTP1.1
resp.setHeader("Pragma", "no-cache");//HTTP1.0
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}

web.xml配置

1
2
3
4
5
6
7
8
9
10
11
12
<filter>
<filter-name>DynamicResourceNoCacheFilter</filter-name>
<filter-class>com.gaoshiyi.web.filter.DynamicResourceNoCacheFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DynamicResourceNoCacheFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>

3. 控制静态资源时间缓存的过滤器
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
55
package cn.imeina.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class StaticResourceNeedCacheFilter implements Filter {
private FilterConfig fConfig;
public StaticResourceNeedCacheFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//该段代码可以在HttpServlet源码中service方法中找到...
HttpServletRequest req;
HttpServletResponse resp;
try {
req = (HttpServletRequest) request;
resp = (HttpServletResponse) response;
} catch (Exception e) {
throw new RuntimeException("non-http request or response");
}
//根据用户访问的资源类型,读取配置文件设置指定资源的缓存时间
String requestURI = req.getRequestURI();
String cacheTime = "0";
if (requestURI.endsWith(".html")) {
//访问html资源
cacheTime = fConfig.getInitParameter("html");
}else if (requestURI.endsWith("css")) {
//访问css资源
cacheTime = fConfig.getInitParameter("css");
}else if (requestURI.endsWith("js")) {
//访问js资源
cacheTime = fConfig.getInitParameter("js");
}
//设置静态资源缓存时间
long time = Long.parseLong(cacheTime) * 60 * 60 * 1000;
resp.setDateHeader("Expires", System.currentTimeMillis() + time);
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
this.fConfig = fConfig;
}
}

web.xml配置

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
<filter>
<filter-name>StaticResourceNeedCacheFilter</filter-name>
<filter-class>com.gaoshiyi.web.filter.StaticResourceNeedCacheFilter</filter-class>
<init-param>
<param-name>html</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>css</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>js</param-name>
<param-value>3</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>StaticResourceNeedCacheFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>StaticResourceNeedCacheFilter</filter-name>
<url-pattern>*.css</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>StaticResourceNeedCacheFilter</filter-name>
<url-pattern>*.js</url-pattern>
</filter-mapping>


4. 自动登录过滤器
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
55
56
57
58
59
package cn.imeina.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.gaoshiyi.web.domain.User;
import com.gaoshiyi.web.service.BusinessService;
import com.gaoshiyi.web.service.impl.BusinessServiceImpl;
import com.gaoshiyi.web.utils.Base64;
public class AutoLoginFilter implements Filter {
private BusinessService service = new BusinessServiceImpl();
public AutoLoginFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 该段代码可以在HttpServlet源码中service方法中找到...
HttpServletRequest req;
HttpServletResponse resp;
try {
req = (HttpServletRequest) request;
resp = (HttpServletResponse) response;
} catch (Exception e) {
throw new RuntimeException("non-http request or response");
}
HttpSession session = req.getSession();
Object loginUser = session.getAttribute("user");
if (loginUser == null) {// 未登录
//获取Cookie并自动登录
Cookie[] cookies = req.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
if ("loginInfo".equals(cookies[i].getName())) {
String value = cookies[i].getValue();
String username = Base64.decode(value.split("\\_")[0]);
String password = value.split("\\_")[1];
User user = new User(username, password, null);
user = service.login(user);
if (user != null) {
session.setAttribute("user", user);
System.out.println("自动登录成功...");
}
break;
}
}
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.gaoshiyi.web.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.beanutils.BeanUtils;
import com.gaoshiyi.web.domain.User;
import com.gaoshiyi.web.service.BusinessService;
import com.gaoshiyi.web.service.impl.BusinessServiceImpl;
import com.gaoshiyi.web.utils.Base64;
/**
* 控制器
* @author AKid
*
*/
public class ControllerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public ControllerServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String opt = request.getParameter("opt");
if ("login".equals(opt)) {
login(request, response);
}
}
/**
* 登录
* @param request
* @param response
* @throws IOException
*/
private void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
Map<String, String[]> map = request.getParameterMap();
User user = new User();
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
BusinessService service = new BusinessServiceImpl();
User loginUser = service.login(user);
if (loginUser == null) {
response.getWriter().write("用户名或密码错误,请重新登录...");
response.setHeader("refresh", "1,url=" + request.getContextPath() + "/login.jsp");
return;
}
//判断用户是否为自动登录
String autologin = request.getParameter("autologin");
if (autologin != null) {
System.out.println("用户设置为自动登录...");
//Cookie为用户登录信息 base64加密用户名_原始密码
Cookie cookie = new Cookie("loginInfo", Base64.encode(user.getUsername()) + "_" + user.getPassword());
cookie.setMaxAge(10 * 24 * 60 * 60);//单位s
cookie.setPath(request.getContextPath());//创建cookie时默认path为当前servlet的上级目录
response.addCookie(cookie);
}
HttpSession session = request.getSession();
session.setAttribute("user", loginUser);
response.getWriter().write("登录成功,跳转中...");
response.setHeader("refresh", "1,url=" + request.getContextPath() + "/main.jsp");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
5. 过滤器高级设置
1
2
3
4
5
6
7
8
9
10
11
<filter>
<filter-name>HighConfigFilter</filter-name>
<filter-class>com.gaoshiyi.web.filter.HighConfigFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HighConfigFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher><!-- 针对直接访问的资源进行过滤 -->
<dispatcher>FORWARD</dispatcher><!-- 针对间接动态包含的资源进行过滤 -->
<dispatcher>INCLUDE</dispatcher><!-- 针对间接转发的资源进行过滤 -->
</filter-mapping>

小知识:
Base64编码原理:
将3字节(24位)–>4字节(32位):取每个字节的前6位最高位补00
1001 1010 0011 1100 1011 1110
0010010 00100011 00110010 00111110 每个字节的取值范围00000000~00111111(0-63共64个整数)
Base64是一个码表
Base64编码会把3字节的二进制数据编码为4字节的文本数据,长度增加33%,好处是编码后的文本数据可以在邮件正文、网页等直接显示。如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用\x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。

Base64码表

base64码表

如果帮到了你,想打赏支持,喏~