您的位置:首页 > 理论基础 > 计算机网络

J2EE(03) HttpServlet Filter的使用

2012-02-12 19:47 267 查看
servlet过滤器是小型的web组件,它能够处理传入的请求和传出的响应。Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开servlet时处理response。它具有高度的透明性,无需更改应用程序代码,就可以根据需要添加、修改或从应用程序中将它删除。

一个filter 包括:

1. 在servlet被调用之前截获;

2. 在servlet被调用之前检查servlet request;

3. 根据需要修改request头和request数据;

4. 根据需要修改response头和response数据;

5. 在servlet被调用之后截获.

你能够配置一个filter 到一个或多个servlet;单个servlet或servlet组能够被多个filter 使用。几个实用的filter包括:用户辨认filter,日志filter,审核filter,加密filter,符号filter,能改变xml内容的XSLT filter等。

一个客户化的过滤器要实现Filter接口的三个方法:init()、destroy()和doFilter()。

1. init():在容器实例化过滤器时调用,该方法接受一个FilterConfig类型的对象做为输入。

2. destroy():执行一些清理操作。

3. doFilter():类似servlet的doPost()、doGet()方法,执行具体的过滤任务。

下面给出一个可执行程序范例,它包含main函数,也可以部署到web应用中。


package utils;




import java.io.IOException;


import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;


import bean.User;


public class UrlFilter implements Filter {




@SuppressWarnings("unused")


private FilterConfig filterConfig;


private FilterChain chain;


private HttpServletRequest request;


private HttpServletResponse response;


public void destroy() {


this.filterConfig = null;


}




public void init(FilterConfig filterConfig) throws ServletException {


this.filterConfig = filterConfig;


}




public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse, FilterChain chain)


throws IOException, ServletException {


this.chain = chain;


this.request = (HttpServletRequest) servletRequest;


this.response = ((HttpServletResponse) servletResponse);


String url = request.getServletPath();


if (url == null)


url = "";


HttpSession session = request.getSession();


User user = (User) session.getAttribute("user");


if (noFileUrl(url, request)) { //不需要判断权限的请求如登录页面,则跳过


chain.doFilter(request, response);


} else if (user == null) {


String action = request.getParameter("action");


if (!"login".equals(action)) {


response.sendRedirect("/zmdsl/admin/index.jsp");//返回登录页面


}


} else {


verifyUrl(url, user);//判断当前user是否拥有访问此url的权限


}


}


/**


*


* @param url 当前请求的url


* @param user 当前登录用户


* @throws IOException


* @throws ServletException


*/


private void verifyUrl(String url, User user)throws IOException, ServletException {


// 获取user拥有的所有资源串


Set<String> royurl = new HashSet<String>();


royurl.add("/newsAction.do?action=adminQueryPage&typeId=3");//为用户分配访问此地址的权限。在真正项目中,此Set集合可能要


//通过查询数据库user、role、menu等表,来获取当前用户所拥有的全部可访问资源


if (royurl != null && royurl.size() > 0


&& pass(royurl, url, request.getParameterMap())){


chain.doFilter(request, response);


} else {


response.setContentType("text/html;charset=GBK");


response


.getWriter()


.println(


"<div style='margin: 100 auto;text-align: center;"


+ "font: bold 18px 宋体;color: #0066CC;vertical-align: middle'> Sorry,您没有权限访问该资源!</div>");


}


}




/**


* 是否需要判断权限,如客户端浏览、登录页面则不需要判断权限


*/




protected boolean noFileUrl(String url, HttpServletRequest request) {


if (url.indexOf("/index.jsp") >= 0 || url.indexOf("login") > 0) {


return true;


}


return false;


}




/**


* 判断该用户是否有权请求该url


* @param royurl user拥有的授权的的url串集合


* @param url 当前请求的url


* @param reqmap 当前request的参数


* @return 是否通过该url


*/




protected boolean pass(Set royurl, String url, Map reqmap) {


boolean match = true;


for (Iterator iter = royurl.iterator(); iter.hasNext();) {


// 获取资源


match = true;


String res_string = (String) iter.next();


if (res_string.indexOf("*") > 0) {


res_string = res_string.substring(0, res_string.indexOf("*"));


if (url.substring(0, res_string.length()).equalsIgnoreCase(res_string)) {


return true; //增加通配符比较


}


}


// 分割url与参数


String[] spw = res_string.split("\\?"); //用"\\?" 转义后即可得到正确的结


if (url.indexOf(spw[0]) < 0) {//为了方便,没有写成spw[0].equals(url)


match = false;


}




if (match && spw.length > 1) {


String[] spa = spw[1].split("\\&"); // 分拆各参数


for (int j = 0; j < spa.length; j++) {


String[] spe = spa[j].split("="); // 分拆键与值


String key = spe[0];


String value = "";


if (spe.length > 1) {


value = spe[1].trim();


}


// 轮询


String[] values = (String[]) reqmap.get(key);


if (values != null) {


for (int k = 0; k < values.length; k++) {


if (value.equalsIgnoreCase(values[k])) {


match = true;


break;


}


match = false;


}


if (!match) {


break;


}


}


}


}


if (match) {


break;


}


}


return match;


}




@SuppressWarnings("unchecked")


public static void main(String[] args) {


UrlFilter filter = new UrlFilter();


Set royurl = new HashSet();//可访问的URL集合


royurl.add("/newsAction.do?typeId=1");


royurl.add("/newsAction.do?typeId=2");




//typeId为1时可以访问,true


String url_1 = "/newsAction.do";


Map reqmap_1 = new HashMap();


reqmap_1.put("typeId", new String[]{"1"});


System.out.println("match false:" + filter.pass(royurl, url_1, reqmap_1));




//typeId为3时不可以访问,false


String url_2 = "/newsAction.do";


Map reqmap_2 = new HashMap();


reqmap_2.put("typeId", new String[]{"3"});


System.out.println("match false:" + filter.pass(royurl, url_2, reqmap_2));




//url就不同,不可访问,false


String url_3 = "/imageAction.do";


Map reqmap_3 = new HashMap();


reqmap_3.put("typeId", new String[]{"3"});


System.out.println("match false:" + filter.pass(royurl, url_3, reqmap_3));


}


}



配置 Servlet过滤器:

非常简单,只需要在web.xml中加入类似下面的代码就可将过滤器部署到应用程序。


<!--================权限 设置================-->


<filter>


<filter-name>Authentication</filter-name>


<filter-class>utils.UrlFilter</filter-class>


<init-param>


<param-name>onError</param-name>


<param-value>/index.jsp</param-value>


</init-param>


</filter>




<filter-mapping>


<filter-name>Authentication</filter-name>


<!-- 只过滤 .jsp 结尾的url, 其余的如 .do, .html, .jpg, .css 等不作过滤-->


<url-pattern>*.do</url-pattern>


</filter-mapping>
其中<filter-Class>是过滤器的路径;<filter-mapping>定义了该过滤器只过滤以.do结尾的URL,当然你也可以稍做修改让它过滤.jsp文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: