Filter是Web编程里一把利器,它本质上就是一个拦截器,但实际应用中很灵活,用途也很广,下面是本人在开发中对filter应用的一个小结:
1)转换字符编码
中文网页编码常用的就是gb2312或是UTF-8,但TOMCAT会默认用编码iso-8859-1,所以需要把所有经过TOMCAT的中文字符进行转换,如果手动在request里改很麻烦,可以用一个filter对所有的request进行拦截,进行编码转换,一劳永逸
2)管理Hibernate的session
在Web 里用Hibernate常常是把session绑定到线程,但往往要求一个session在一个请求的活动中都有效,这样可以保证同一活动中能共享 lazy bean。用filter能到达这个目的,在doFilter之前绑定session到线程,在doFilter后关闭session,这样既可以保证 session不会泄漏,也能让lazy bean在同一请求周期里共享
3)做权限审查
在web层里需要对很多资源进行逻辑类似的安全保障,通过filter可以在调用这些资源前加上一个屏障,这样既可以把安全代码和逻辑代码相分离,也可以很好的reuse这些安全模块
4)做cache
在web层常常需要对一些请求返回进行缓存,这样可以有效的减轻服务器的压力,filter可以对请求进行拦截,查询缓存,若有效则直接返回缓存内容,若无效则进行实际的服务器请求,返回给用户,并对缓存进行更新,以备下次请求
5)做拦截器的代理
有的时候需要把一些拦截器用到web层,filter可以很好地充当代理的角色,比如可以在Spring里做好拦截器的Bean,再通过filter把这些Bean和相应的web请求桥接起来。
6)过滤特殊字符
有时需要过滤特殊字符,比如防止sql注入,Filter可以很好达到这个目的
· doFilter(ServletRequest request,ServletResponse response,FilterChain next) throws IOException,ServletException{
·
· HttpServletRequest req = (HttpServletRequest)request;
· HttpServletResponse resp = (HttpServletResponse)response;
· HttpSession session = req.getSession();
· String requesturi = req.getRequestURI();
· if(requesturi.endsWith("css")
· || requesturi.endsWith("js")
· || requesturi.endsWith("login.jsp")
· || requesturi.endsWith("login.action")
· || requesturi.endsWith("Logout.action")
· || session.getAttribute(Constants.USER_KEY) != null){
·
· next.doFilter(request, response);
·
· }else if(session.getAttribute(Constants.USER_KEY) == null
· ){
·
· resp.sendRedirect("/PowerGrid/login.jsp");
· }
众所周知,如果没有对页面进行权限控制,用户只要输入URL就能进入任何页面。
下面就演示一下最基本的使用Fiter来控制页面的权限。
1.写一个FILTER,用来判断用户是否有权限进入指定页面。
java 代码
1 import java.io.IOException;
2
3 import javax.servlet.Filter;
4 import javax.servlet.FilterChain;
5 import javax.servlet.FilterConfig;
6 import javax.servlet.ServletException;
7 import javax.servlet.ServletRequest;
8 import javax.servlet.ServletResponse;
9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 import javax.servlet.http.HttpSession;
13
14 import org.apache.log4j.Logger;
15
16 import com.kiral.action.UserAction;
17 import com.kiral.model.User;
18
19 /*******************************************************************************
20 * 在过滤器中实现权限控制类,用来检验用户是否有权限进入当前页面
21 *
22 * @作者:kiral
23 * @日期:2006-6-24
24 * @版本: 1.0
25 ******************************************************************************/
26 public class FilterServlet extends HttpServlet implements Filter {
27 private static final long serialVersionUID = 5162189625393315379L;
28
29 private static Logger LOG = Logger.getLogger(FilterServlet.class);
30
31 /**
32 * 配置允许的角色
33 */
34 private String allowRole = null;
35
36 /**
37 * 重定向的URL
38 */
39 private String redirectURl = null;
40
41 public void init(FilterConfig filterConfig) throws ServletException {
42 // 得到允许的角色,这个参数是由web.xml里的allowRole所指定
43 allowRole = filterConfig.getInitParameter("allowRole");
44 // 指定要重定向的页面
45 redirectURl = "/locker/index.html";
46 }
47
48 /**
49 * 在过滤器中实现权限控制
50 */
51 public void doFilter(ServletRequest sRequest, ServletResponse sResponse,
52 FilterChain filterChain) throws IOException, ServletException {
53 HttpServletRequest request = (HttpServletRequest) sRequest;
54 HttpServletResponse response = (HttpServletResponse) sResponse;
55 HttpSession session = request.getSession();
56
57 // 如果回话中的用户为空,页面重新定向到登陆页面
58 if (session.getAttribute(UserAction.CURRENT_USER) == null) {
59 response.sendRedirect(redirectURl);
60 }
61 // 会话中存在用户,则验证用户是否存在当前页面的权限
62 else {
63 User user = (User) session.getAttribute(UserAction.CURRENT_USER);
64 try {
65 // 如果用户没有当前页的权限,页面重新定向到登陆页面
66 if ("0".equals(allowRole) || user.hasPower(allowRole)) {
67 filterChain.doFilter(sRequest, sResponse);
68 } else {
69 // 过滤器经过过滤后,过滤链继续传递请求和响应
70 response.sendRedirect(redirectURl);
71 }
72 } catch (Throwable e) {
73 LOG.error("权限过滤时候出现错误", e);
74 throw new RuntimeException("权限过滤时候出现错误", e);
75 }
76 }
77 }
78
79 public void destroy() {
80 }
81
82 }
在web.xml中配置要过滤的页面和能进入当前页面的角色
xml 代码
83
84 <filter>
85 <filter-name>UserAdminfilter-name>
86
87 <filter-class>com.emap.web.FilterServletfilter-class>
88
89 <init-param>
90
91 <param-name>allowRoleparam-name>
92 <param-value>1param-value>
93 init-param>
94 filter>
95 <filter-mapping>
96 <filter-name>UserAdminfilter-name>
97 <url-pattern>/jsp/security/*url-pattern>
98 filter-mapping>
上面配置的意思是说,当用户进入/jsp/security文件夹下的页面的时候,程序会进入FilterServlet里的doFilter方法里,进行权限判断。
其他的页面权限控制:
1.你可以在filter里判断用户是否登录,然后需要特殊权限能访问的页面,在页面里进行判断。
2.推荐使用开源框架ACEGI来进行权限控制。