无为

无为则可为,无为则至深!

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks

同servlet非常类似,Filter就是JAVA组件,请求发送到servlet前,可以使用过滤器Filter截获和处理请求,同时servlet结束以后,响应发回以前同样可以使用过滤器Filter处理响应。WEB容器可以用web.xml部署文件声明何时调用过滤器Filter。

过滤器Filter主要功能是:1、完成安全检查;2、重新格式化请求首部或体;3、建立请求审计或记录日志---请求过滤器Filter

1、压缩响应流;2、追加或者修改响应流;3、创建一个定制响应---响应过滤器Filter


同servlet一样,过滤器Filter也具有生命周期:init()->doFilter()->destroy().要实现模块化,FilterChain功不可末,它可以采用不同的方式组合过滤器,协调完成一些事情,它由部署文件中的filter元素驱动,和Filter都在javax.servlet包中。在servlet2.4中,过滤器同样可以用于请求分派器,但须在web.xml中声明,<dispatcher>INCLUDE或FORWARD或REQUEST或ERROR</dispatcher>该元素位于filter-mapping中。


1、实现一個Filter,代码如下:

public class MyFilter implements Filter {

public void init(FilterConfig arg0) throws ServletException {

}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException{


HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse)response;
CachedResponseWrapper wrapper = new CachedResponseWrapper(httpResponse);
// 写入wrapper:
chain.doFilter(request, wrapper);
// 首先判断status, 只对200状态处理:
if(wrapper.getStatus()==HttpServletResponse.SC_OK) {
// 对响应进行处理,这里是进行GZip压缩:
byte[] data = GZipUtil.gzip(wrapper.getResponseData());
httpResponse.setContentType(getContentType());
httpResponse.setContentLength(data.length);
httpResponse.setHeader("Content-Encoding", "gzip");

ServletOutputStream output = response.getOutputStream();
output.write(data);
output.flush();
}
}

public void destroy() {

}

}


2、实现一个HttpServletResponseWrapper

public class CheckFrameHttpServletResponseWrapper extends
HttpServletResponseWrapper {

public CheckFrameHttpServletResponseWrapper(HttpServletResponse response) {

super(response);
}

public PrintWriter getWriter() throws IOException{
return new CheckFrameWriter(super.getWriter());
}

}

3、实现一个Writer

public class CheckFrameWriter extends PrintWriter {
String checkString = "<script>\n if(window.top.frames.length==0){\n"
+ "window.location.href=\"https://aix:9080/sso/mainlayout.faces?"
+ "contentURL=http://aix:9080/security/paramsMaintain/"
+ "addParams.faces?roleId=0001\"\n" + "}\n</script>\n";

public CheckFrameWriter(Writer out) {
super(out);
}

public void write(int c) {
super.write((char) c);
}

public void write(char buf[], int off, int len) {
StringBuffer sb = new StringBuffer(len);
for (int i = 0; i < len; i++) {
sb.append(buf[off + i]);
}
String s = sb.toString();
int bodyIndex = s.indexOf("<body>");
if (bodyIndex > -1) {
String part1 = s.substring(0, bodyIndex);
String part2 = s.substring(bodyIndex );
s = part1 + checkString + part2;
}
for (int i = 0; i < s.length(); i++) {
write(s.charAt(i));
}
}

public void write(String s, int off, int len) {
for (int i = 0; i < len; i++) {
write(s.charAt(off + i));
}
}
}


在Writer中,你便可以随心所欲的修改Response的內容了。

4、在Web.xml中加入相应的配置元素,对JSP进行拦截。



凡是有该标志的文章,都是该blog博主Caoer(草儿)原创,凡是索引、收藏
、转载请注明来处和原文作者。非常感谢。

posted on 2007-07-25 13:56 草儿 阅读(7244) 评论(3)  编辑  收藏 所属分类: Web Data MiningJAVA WEB应用

Feedback

# re: JAVA组件过滤器Filter[未登录] 2007-07-25 16:33 刘明
正好问问。

我做了一个过滤器,我想过滤某一组资源里的某几个资源该怎么做呢?配置多个servlet-mapping不可行啊。

<filter>
<filter-name>AuditFilter</filter-name>
<filter-class>com.wrox.projsp.ch14.filters.AuditFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>AuditFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

以上的配置是对所有资源的过滤,如果我只想过滤里面的几个资源呢?比如过滤一个html、2个jsp什么的,怎么做呢?谢谢。  回复  更多评论
  

# re: JAVA组件过滤器Filter 2007-07-26 00:34 草儿
我个人的解决方案是:1、采用目录分割<url-pattern>/html/*</url-pattern>
<url-pattern>/jsp/*</url-pattern>
自然会根据url模式匹配过滤器;
2、在web.xml部署多个filter元素,然后在实现Filter接口定制过滤器类中有doFilter()方法调用;  回复  更多评论
  

# re: JAVA组件过滤器Filter[未登录] 2007-07-26 09:34 刘明
谢谢草儿。

嗯。。。是个问题,感觉控制力还是不够啊。看来应用的时候还是有个好的设计才行。  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: