HttpServletRequestWrapper,HttpServletResponseWrapper在过滤器Filter中的使用

Servlet规范中所引入的filter令人心动不已,因为它引入了一个功能强大的拦截模式。Filter是这样一种Java对象,它能在request到达servlet的服务方法之前拦截HttpServletRequest对象,而在服务方法转移控制后又能拦截HttpServletResponse对象。你可以使用filter来实现特定的任务,比如验证用户输入,以及压缩web内容。但你拟富有成效地使用过滤器的念头却被你不能改变HttpServletRequest对象的参数的现实扫了兴,因为java.util.Map所包装的HttpServletRequest对象的参数是不可改变的。这极大地缩减了filter的应用范围。至少在一半的时间里,你希望可以改变准备传送给filter的对象。如果在HttpServletRequest对象到达Struts的action servlet之前,我们可以通过一个filter将用户输入的多余空格去掉,而响应的时候将响应内容压缩后在输出,难道不是更美妙吗?这样的话,幸运的是,尽管你不能改变不变对象本身,但你却可以通过使用装饰模式来改变其状态。

现在,让我们来看看,如何编写自己的HttpServletRequest装饰类。


实例:


1、编码过滤以及请求信息中的字符处理:

 httpservletRequest 装饰类

package soufun.com;

importjava.io.UnsupportedEncodingException;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletRequestWrapper;

importorg.apache.commons.lang.StringEscapeUtils;

/**

 *@author WHD

 *data 2015年8月23日

 */

// HttpServletRequestWrapper 类实现了HttpServletRequest这个接口
// 继承这个实现类,进行方法重写来实现对请求信息的修改操作
 public class  EscapeWrapper  extends  HttpServletRequestWrapper {

public EscapeWrapper(HttpServletRequest request) {

super(request);

//TODO Auto-generated constructor stub

}

@Override

// 之前我们的过滤器不能对请求参数进行操作,但现在我们可以使用这个装饰模式对请求参数进行操作

// 重写getParameter(String str)方法 来操作请求参数

publicString  getParameter(String name){

// 获取请求参数

Stringvalue= getRequest().getParameter("name");

System.out.println("修改前"+value);

try { // 编码设置

byte[]by= value.getBytes("ISO8859-1");

// 编码过滤器,这里的编码是自己定义的编码

value= new String(by,"utf-8");

}catch (UnsupportedEncodingException e) {

//TODO Auto-generated catch block

e.printStackTrace();

}

//这里可以对内容进行相应的操作

value=value.replaceAll("a","b");

System.out.println("修改后"+value);

returnvalue;

}

}

 

过滤器使用装饰类来处理请求参数:

package soufun.com;

importjava.io.IOException;

importjavax.servlet.Filter;

importjavax.servlet.FilterChain;

importjavax.servlet.FilterConfig;

importjavax.servlet.ServletException;

importjavax.servlet.ServletRequest;

importjavax.servlet.ServletResponse;

importjavax.servlet.http.HttpServletRequest;


/**

 *@author WHD

 *data 2015年8月23日

 */

public class Filter2   implements Filter{

@Override

publicvoid destroy() {

//TODO Auto-generated method stub

}

 
@Override

publicvoid doFilter(ServletRequest arg0, ServletResponse arg1,

FilterChainchain) throws IOException, ServletException {

     // 在这里给FilterChain 传递的参数是传装饰后的request,之后调用的就是EscapeWrapper重写的getParameter(String name )这个方法
     // 获取装饰后的Request对象
      HttpServletRequest  request =newEscapeWrapper((HttpServletRequest)arg0);
    // 使用过滤器就是在请求到大server之前,调用service(HttpServletRequest request,HttpServletResponse response)之前将request对象替换为装饰后的request对象
    // 只要使用了这个过滤器的请求的reques对象都会被替换为装饰后的request 对象,这样之后调用的getParameter(String str)方法自然就是装饰后的类的方法
    
     chain.doFilter(request, arg1);

}


@Override

publicvoid init(FilterConfig arg0) throws ServletException {

//TODO Auto-generated method stub

}

}

 

2、响应信息压缩后返回

 
压缩流的创建:

package soufun.com;

importjava.io.IOException;

importjava.util.zip.GZIPOutputStream;

importjavax.servlet.ServletOutputStream;


/**

 *@author WHD

 *data 2015年8月23日

 */

// 扩展输出流

public class GZipServletOutputStream  extendsServletOutputStream{

// 定义压缩输出流

privateGZIPOutputStream gzipOutputStream;

// 构造函数来创建压缩输出流

public GZipServletOutputStream(ServletOutputStream servletOutputStreams) throwsIOException{

 gzipOutputStream= newGZIPOutputStream(servletOutputStreams);

}

@Override

// write 方法重写

public void write(int b) throws IOException {

//TODO Auto-generated method stub

gzipOutputStream.write(b);

}

public GZIPOutputStream getGzipOutputStream() {

returngzipOutputStream;

}

public void setGzipOutputStream(GZIPOutputStream gzipOutputStream) {

this.gzipOutputStream= gzipOutputStream;

}

}


 httpservletResponse装饰类

package soufun.com;


importjava.io.IOException;

importjava.io.OutputStreamWriter;

importjava.io.PrintWriter;

importjava.util.zip.GZIPOutputStream;

importjavax.servlet.ServletOutputStream;

importjavax.servlet.http.HttpServletResponse;

importjavax.servlet.http.HttpServletResponseWrapper;

 

/**

 *@author WHD

 *data 2015年8月23日

 */

public class  CompressionWrapper  extends  HttpServletResponseWrapper {

privateGZipServletOutputStream gzServletOutputStream;

privatePrintWriter printWriter;

public CompressionWrapper(HttpServletResponse response) {

super(response);

//TODO Auto-generated constructor stub

}

 
@Override

public ServletOutputStream getOutputStream() throws IOException {

if(printWriter!= null) {

thrownew IllegalStateException();

}

if(gzServletOutputStream == null) {

gzServletOutputStream= new GZipServletOutputStream(

getResponse().getOutputStream());

}

returngzServletOutputStream;

}

 

@Override

// getWrite() 方法重写,实现压缩输出流

public PrintWriter getWriter() throws IOException {

if(gzServletOutputStream!= null) {

thrownew IllegalStateException();

}

if(printWriter == null) {

gzServletOutputStream= new GZipServletOutputStream(

getResponse().getOutputStream());

OutputStreamWriterosw = newOutputStreamWriter(gzServletOutputStream,getResponse().getCharacterEncoding());

printWriter= new PrintWriter(osw);

}

returnprintWriter;

}


@Override

public void setContentLength(int len) {}

publicGZIPOutputStream getGZIPOutputStream() {

if(this.gzServletOutputStream == null) {

returnnull;

}

returnthis.gzServletOutputStream.getGzipOutputStream();

}

}


过滤器使用httpservletResponse 的装饰类

package soufun.com;


importjava.io.IOException;

importjava.util.zip.GZIPOutputStream;

importjavax.servlet.Filter;

importjavax.servlet.FilterChain;

importjavax.servlet.FilterConfig;

importjavax.servlet.ServletException;

importjavax.servlet.ServletRequest;

importjavax.servlet.ServletResponse;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;


/**

 *@author WHD

 *data 2015年8月23日

 */

public class CompressionFilter implements Filter{

 

@Override

publicvoid destroy() {

//TODO Auto-generated method stub

}


@Override

public void doFilter(ServletRequest request, ServletResponse response,

FilterChainchain) throws IOException, ServletException {

//TODO Auto-generated method stub

HttpServletRequest req = (HttpServletRequest) request;

HttpServletResponse res = (HttpServletResponse) response;

String encodings = req.getHeader("accept-encoding");

//判断浏览器是否支持gzip输出

if((encodings != null) && (encodings.indexOf("gzip") > -1)){

// 创建装饰后的resposne对象

CompressionWrapper responseWrapper =new CompressionWrapper(res);

responseWrapper.setHeader("content-encoding","gzip");

// 这里传递的是装饰后的Response对象,所以printwrite 使用的是压缩输出
// 使用过滤器就是将所有的响应在到大浏览器之前将原来的Response 替换为装饰后的Response对象

chain.doFilter(request,responseWrapper);

GZIPOutputStreamgzipOutputStream = responseWrapper.getGZIPOutputStream();

if(gzipOutputStream != null) {

gzipOutputStream.finish();

}

}

else{

chain.doFilter(request,response);

}

}


@Override

publicvoid init(FilterConfig arg0) throws ServletException {

//TODO Auto-generated method stub


}

}

 


总结:

1、Filter的配置和Servlet的配置是一样的

 <filter>
  <filter-name>filter2</filter-name>
  <filter-class>soufun.com.Filter2</filter-class>
  <init-param>
  <param-name>utf8</param-name>
  <param-value>GBK</param-value>
  </init-param>
  </filter>
  <filter-mapping>
  <filter-name>filter2</filter-name>
  <url-pattern>/*</url-pattern>

  </filter-mapping>


2、继承HttpServletRequestWrapper 和HttpServletResponse 两个类对 getParameter(String str) 和getWrite()两方法进行重写,而方法中实现我们想要的操作

3、使用Filter过滤器,我们知道Filter是在请求到达servlet之前和servlet响应信息到达浏览器之前进行两次拦截,而就在到达server之前我们将FilterChain的doFilter(request,reponse)方法的request参数替换为我们装饰后的request而我们又重写的getParameter(String str)方法,之后调用的就是这个方法,因此也就完成了

请求参数的过滤和修改

4、响应和请求其实是一样的,也是替换了Response对象,从而调用我们重写的方法实。




  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值