使用java的过滤器filter备忘(HttpServletResponseWrapper)

本文介绍了一种在WebLogic 8.1.4环境下实现HTTP响应包装的方法,通过自定义ResponseWrapper类来缓存输出内容,适用于简单的页面布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

测试中间件是weblogic8.1.4,jdk 是weblogic 自带的1.42

网上看到很多HttpServletResponseWrapper 的继承类的实现方法,最简单就是通过CharArrayWriter 对象缓存输出字符,但是这种方式只能在tomcat 中可以实现,在weblogic 中无法实现,因为weblogic 只能用流操作输出,下面的ResponseWrapper 代码是我试了很多次,终于在weblogic 上可以实现了。

但是个人是不建议使用ResponseWrapper 的,对于复杂页面,多层嵌套,多个编码组成的页面,单就乱码等就搞死人了,复杂的页面布局也不一定能正确显示。

一般用于简单构成页面,并且过滤器最好指定特定的地址。

在过滤器中写上下面这些, 最好加上try-catch-finally, 乱码问题自行解决

ResponseWrapper mr = new ResponseWrapper(response);    //定义好ResponseWrapper 对象,这个时候response 里面的流就写入到ResponseWrapper 对象里面了

chain.doFilter(request, mr);   //传给下一个过滤器

ServletOutputStream out = resp.getOutputStream();    //注意weblogic 的话,getReader 和getOutputStream 两者只能调用其中一个,weblogic 默认调用了getOutputStream,调用getReader 会报异常。

String result = new String(mr.getResponseData());  //获取输出内容

response.setContentLength(-1);                 //避免输出内容有差错,写上这个

out.write(result.getBytes(), 0, result.length());         //重新输出内容

out.flush();
out.close();

下面都是ResponseWrapper 的代码,要全部搬上去,已经通过了weblogic8.1.4 的测试

package filters;

import java.io.ByteArrayOutputStream;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
 
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpServletRequestWrapper;
 
 
public class ResponseWrapper extends HttpServletResponseWrapper {
    private ByteArrayOutputStream buffer = null;

    private ServletOutputStream out = null;

    private PrintWriter writer = null;
 
    public ResponseWrapper(HttpServletResponse response) throws IOException {
        super(response);
        
        buffer = new ByteArrayOutputStream();
        out = new WapperedOutputStream(buffer);

        writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding()));
    }
 
    public PrintWriter getWriter() throws IOException {
        return writer;
    }
 
    public ServletOutputStream getOutputStream() throws IOException {
        return out;
    }


    public void flushBuffer() throws IOException {
        if (out != null) {
        	out.flush();
        }
        if (writer != null) {
            writer.flush();
        }
    }
    
    public void reset() {
        buffer.reset();
    }
    
    public byte[] getResponseData() throws IOException {
        flushBuffer();
        return buffer.toByteArray();
    }
 
}

package filters;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.servlet.ServletOutputStream;

public class WapperedOutputStream extends ServletOutputStream {

	private ByteArrayOutputStream bos = null;

    public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
        bos = stream;
    }


    public void write(int b) throws IOException {

        bos.write(b);

    }

}


<think>好的,我需要回答用户关于Java Filter过滤器中对响应数据进行操作的问题。首先,我得回忆一下Java Filter的基本概念。Filter主要用于拦截请求和响应,进行预处理或后处理。用户特别关注对响应的数据操作,所以需要重点讲解这方面的内容。 接下来,我应该分步骤解释。首先,Filter的工作原理,尤其是响应处理的部分。可能需要提到Filter链,以及如何包装响应对象。然后,具体说明如何操作响应数据,比如使用HttpServletResponseWrapper来修改内容。 需要注意用户提到的系统级指令,比如用中文回答,行内数学表达式用$...$,但这个问题可能不需要数学公式,所以重点在代码示例和结构。需要确保LaTeX语法正确,但代码部分应该用代码块标记。 用户可能想知道实际应用场景,比如修改HTML、压缩数据、添加头部信息等。需要举几个例子,比如替换敏感词、GZIP压缩,或者添加缓存头。同时,要强调Filter的执行顺序和配置方法,比如web.xml或注解。 还需要注意常见问题,比如正确传递包装后的响应对象,避免关闭输出流多次,以及性能问题。可能应该提到字符编码的处理,确保不乱码。 最后,结构要清晰,分点说明,比如实现步骤、示例代码、应用场景和注意事项。确保用户能够一步步理解和实现响应数据的操作。</think>在Java Web开发中,Filter过滤器可通过包装响应对象实现对响应数据的拦截和修改。以下是分步骤说明: --- ### 一、Filter处理响应的核心原理 1. **拦截流程** Filter通过`doFilter()`方法拦截请求,在调用`chain.doFilter()`后,可对后续Servlet处理完毕的响应数据进行操作。 2. **响应对象包装** 使用`HttpServletResponseWrapper`自定义响应对象,重写`getWriter()`或`getOutputStream()`方法,捕获输出内容。 --- ### 二、操作响应数据的步骤 #### 1. 创建自定义Response包装类 ```java public class CustomResponseWrapper extends HttpServletResponseWrapper { private CharArrayWriter output; public CustomResponseWrapper(HttpServletResponse response) { super(response); this.output = new CharArrayWriter(); } @Override public PrintWriter getWriter() { return new PrintWriter(output); // 捕获写入内容 } public String getContent() { return output.toString(); // 获取原始响应内容 } } ``` #### 2. 在Filter中修改响应内容 ```java public class ModifyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { CustomResponseWrapper wrapper = new CustomResponseWrapper((HttpServletResponse) response); chain.doFilter(request, wrapper); // 传递包装对象 String originalContent = wrapper.getContent(); String modifiedContent = originalContent.replace("敏感词", "***"); // 修改内容 response.getWriter().write(modifiedContent); // 写回修改后的内容 } } ``` --- ### 三、典型应用场景 1. **内容替换** 如敏感词过滤、全局字符串替换(替换静态资源路径) 2. **响应压缩** 使用GZIP压缩输出流: ```java response.setHeader("Content-Encoding", "gzip"); chain.doFilter(request, new GZIPResponseWrapper(response)); ``` 3. **添加统一响应头** ```java @Override public void doFilter(...) { response.addHeader("X-Content-Type-Options", "nosniff"); chain.doFilter(request, response); } ``` --- ### 四、关键注意事项 1. **正确传递包装对象** 必须将自定义的`ResponseWrapper`传递给`chain.doFilter()`,而非原始response对象。 2. **流操作限制** - 避免同时调用`getWriter()`和`getOutputStream()` - 输出流关闭后不可再次写入 3. **性能影响** 频繁操作大文本可能影响性能,建议结合缓存机制。 4. **编码一致性** 需设置与原始响应一致的字符编码: ```java response.setCharacterEncoding("UTF-8"); ``` --- ### 五、配置Filter示例(web.xml) ```xml <filter> <filter-name>modifyFilter</filter-name> <filter-class>com.example.ModifyFilter</filter-class> </filter> <filter-mapping> <filter-name>modifyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` 或使用注解: ```java @WebFilter(urlPatterns = "/*") public class ModifyFilter implements Filter { ... } ``` --- 通过上述方法,Filter可以灵活实现响应内容的动态修改,是处理统一逻辑(如安全过滤、数据压缩)的高效方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值