Java 如何在过滤器中读取ServletResponse主体并向其写入OutputStream?

Java 如何在过滤器中读取ServletResponse主体并向其写入OutputStream?,java,servlets,servlet-filters,Java,Servlets,Servlet Filters,我试图创建一个过滤器,如果url查询参数中有?translate=true,它将使用一个已经存在的库来翻译JSP页面的内容 用户请求路由->JSP页面加载HTML内容->My filter截取响应并使用库函数对其进行修改,并将输出媒体类型更改为纯文本 预定义库接受HTML字符串作为输入,并生成OutputStream作为输出。然后,我应该将OutputStream结果传递给ServletResponse对象 我设法为一个常量字符串(而不是来自响应体的字符串)生成一个翻译,从而使代码变白 pack

我试图创建一个过滤器,如果url查询参数中有
?translate=true
,它将使用一个已经存在的库来翻译JSP页面的内容

用户请求路由->JSP页面加载HTML内容->My filter截取响应并使用库函数对其进行修改,并将输出媒体类型更改为纯文本

预定义库接受HTML字符串作为输入,并生成OutputStream作为输出。然后,我应该将OutputStream结果传递给ServletResponse对象

我设法为一个常量字符串(而不是来自响应体的字符串)生成一个翻译,从而使代码变白

package net.codejava;
导入java.io.*;
导入javax.servlet.*;
导入javax.servlet.annotation.WebFilter;
导入javax.servlet.http.HttpServletResponse;
@WebFilter(“/*”)
公共类ResponseFilter实现过滤器{
@凌驾
public void init(FilterConfig FilterConfig)抛出ServletException{
}
@凌驾
public void doFilter(ServletRequest请求、ServletResponse响应、FilterChain链)
抛出IOException、ServletException{
CharResponseWrapper=新的CharResponseWrapper((HttpServletResponse)响应);
doFilter(请求,包装器);
PrintWriter responseWriter=response.getWriter();
if(wrapper.getContentType()包含(“text/html”)){
CharArrayWriter charWriter=新的CharArrayWriter();
String originalContent=wrapper.toString();
int indexOfCloseBodyTag=originalContent.indexOf(“”-1;
charWriter.write(originalContent.substring(0,indexOfCloseBodyTag));
字符串版权信息=“版权代码java.net

”; 字符串closeHTMLTags=“”; charWriter.write(版权信息); charWriter.write(closeHTMLTags); String alteredContent=charWriter.toString(); response.setContentLength(alteredContent.length()); 响应编写器。编写(更改内容); } } @凌驾 公共空间销毁(){ } }
我尝试使用示例代码并将其与原始代码合并,但它总是给我错误,即我多次使用响应流,并且在提交响应后使用它

我的问题:如何在代码中合并此示例代码,以便能够读取响应对象主体并在代码中动态使用它

换句话说,我如何从ServletResponse对象读取正文字符串,然后写入同一个ServletResponse对象,而不会出现错误,因为我已经使用了方法
setOutStream
wrire
,并且不能使用它们两次。为了能够从流中读取数据并在以后写入数据?

尝试删除“if(translate==null | | |!“true”.equals(translate)){”,并让“doFilter”始终运行,最后删除“chain.doFilter(request,resp);”。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    String translate = ((HttpServletRequest) request).getParameter("translate");
    if(translate == null || !"true".equals(translate)) {
        chain.doFilter(request, response);
        return;
    }
    
    HttpServletResponse resp = new HttpServletResponseWrapper((HttpServletResponse) response) {
        public void setContentType(String ct) {
            super.setContentType("text/plain");
       }
    };
    resp.setContentType("text/plain");
    
    Translator translator = new Translator();
    translator.setTimeout(5000);
    // I need to make this string dynamic. I need it to come from `ServletResponse response`
    translator.loadFromHtml("<html><body><h1>Lorem Ipsum</h1></body></html>");

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    OutputStream outStream = stream;
    translator.setOutStream(outStream);
    try {
        //The outStream will be filled with translation
        translator.translate();
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    ByteArrayOutputStream buffer = (ByteArrayOutputStream) outStream;
    byte[] bytes = buffer.toByteArray();
    ServletOutputStream servletOut = response.getOutputStream();
    servletOut.write(bytes);

    chain.doFilter(request, resp);
}
package net.codejava;
 
import java.io.*;
import javax.servlet.http.*;
 
public class CharResponseWrapper extends HttpServletResponseWrapper {
    private CharArrayWriter writer;
      
    public CharResponseWrapper(HttpServletResponse response) {
        super(response);
        writer = new CharArrayWriter();
    }
      
    public PrintWriter getWriter() {
        return new PrintWriter(writer);
    }
      
    public String toString() {
        return writer.toString();
    }
  
}
package net.codejava;
 
import java.io.*;
 
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
 
@WebFilter("/*")
public class ResponseFilter implements Filter {
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse) response);
         
        chain.doFilter(request, wrapper);
         
        PrintWriter responseWriter = response.getWriter();
         
        if (wrapper.getContentType().contains("text/html")) {
            CharArrayWriter charWriter = new CharArrayWriter();
            String originalContent = wrapper.toString();
             
            int indexOfCloseBodyTag = originalContent.indexOf("</body>") - 1;
              
            charWriter.write(originalContent.substring(0, indexOfCloseBodyTag));
              
            String copyrightInfo = "<p>Copyright CodeJava.net</p>";
            String closeHTMLTags = "</body></html>";
             
            charWriter.write(copyrightInfo);
            charWriter.write(closeHTMLTags);
              
            String alteredContent = charWriter.toString();
            response.setContentLength(alteredContent.length());
            responseWriter.write(alteredContent);          
        }
         
    }
 
    @Override
    public void destroy() {
         
    }
 
}