Java过滤器 - 根据请求有条件地更改响应正文

Posted

技术标签:

【中文标题】Java过滤器 - 根据请求有条件地更改响应正文【英文标题】:Java filter - conditionally change response body based on request 【发布时间】:2017-06-19 07:00:51 【问题描述】:

我有一个 servlet 过滤器,它拦截请求并检查自定义“加密”标头:

public class EncryptionFilter extends GenericFilterBean

@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain) 
    final HttpServletRequest httpRequest = (HttpServletRequest) request;
    if (httpRequest.getHeader("EncryptedCommunication") != null)
        decryptedRequest = /*decrypt request body and forward to next filter*/
        encryptedResponse = /*encrypt request body and forward to next filter*/
        filterChain.doFilter(decryptedRequest, encryptedResponse);
    
    else  /* communication not encrypted */
        filterChain.doFilter(request, response);
    
  

当标头存在时,我应该解密请求正文并加密响应正文。 否则,应保持请求/响应正文不变。

如何仅在需要时更改响应?

【问题讨论】:

【参考方案1】:

你需要使用一个HttpServletResponseWrapper的例子是:

filterChain.doFilter(servletRequest,
        new HttpServletResponseWrapper((HttpServletResponse) servletResponse) 
            @Override
            public void setHeader(String name, String value) 
                if (!HTTPCacheHeader.ETAG.getName().equalsIgnoreCase(name)) 
                    super.setHeader(name, value);
                
            
        );

见http://www.programcreek.com/java-api-examples/javax.servlet.http.HttpServletResponseWrapper

这是如何设置主体的示例:

public class ReadTwiceHttpServletRequestWrapper extends HttpServletRequestWrapper 

private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

public ReadTwiceHttpServletRequestWrapper(HttpServletRequest request) 
    super(request);
    try 
        IOUtils.copy(request.getInputStream(), outputStream);
     catch (IOException e) 
        e.printStackTrace();
    


@Override
public BufferedReader getReader() throws IOException 
    return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(outputStream.toByteArray())));


@Override
public ServletInputStream getInputStream() throws IOException 
    final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
    return new ServletInputStream() 

        @Override
        public int readLine(byte[] b, int off, int len) throws IOException 
            return inputStream.read(b, off, len);
        

        @Override
        public boolean isFinished() 
            return inputStream.available() > 0;
        

        @Override
        public boolean isReady() 
            return true;
        

        @Override
        public void setReadListener(ReadListener arg0) 
            // TODO Auto-generated method stub
        

        @Override
        public int read() throws IOException 
            return inputStream.read();
        
    ;


public void setBody(String body) 
    outputStream = new ByteArrayOutputStream();
    try 
        outputStream.write(body.getBytes());
     catch (IOException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    


public String getBody() 
    return new String(outputStream.toByteArray());

见How to get the XML from POST request and modify it in Servlet Filter?

【讨论】:

这没有回答问题,因为我想更改响应正文而不是标题。

以上是关于Java过滤器 - 根据请求有条件地更改响应正文的主要内容,如果未能解决你的问题,请参考以下文章

Java Servlet中Filter概念的实时用法是什么? [重复]

Tomcat 7:RequestDumperFilter 未记录 HTTP 请求/响应正文

如何使用保留请求正文和响应正文的 servlet 过滤器记录请求和响应?

Java Spring 在处理之前更改响应

HTTP请求头和响应头都有哪些内容

servlet 中读取请求正文的问题