Servlet 响应过滤器不会修改成功请求的响应正文(200 OK),对于异常情况效果很好

问题描述 投票:0回答:1

我有一个 servlet 响应过滤器。我的响应正文不会针对成功的请求进行修改。异常已成功包装并且响应正文已修改。我的代码只是从 O'Reilly Learning Java 第 4 版代码中复制/粘贴,位于 https://learning.oreilly.com/library/view/learning-java-4th/9781449372477/ch15s04.html#:-: text=过滤%20the%20Servlet%20Response

这是书中的代码,根据我的要求进行了少量修改-

public class LinkResponseFilter implements Filter {
    FilterConfig filterConfig;
    public void init(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        WrappedResponse wrappedResponse = new WrappedResponse((HttpServletResponse) res);
        chain.doFilter(req, wrappedResponse);
        wrappedResponse.close();
    }
    public void destroy() {
    }
    static class WrappedResponse extends HttpServletResponseWrapper {
        boolean linkText;
        PrintWriter client;
        WrappedResponse(HttpServletResponse res) {
            super(res);
        }
        public void setContentType(String mime) {
            super.setContentType(mime);
            if (mime.startsWith("application/fhir+json")) {   //BOOK CODE CHECKS FOR html
                linkText = true;
            }
        }
        public PrintWriter getWriter() throws IOException {
            if (client == null) {
                if (linkText) {
                    client = new LinkWriter(super.getWriter(), new ByteArrayOutputStream());
                } else {
                    client = super.getWriter();
                }
            }
            return client;
        }
        void close() {
            if (client != null) {
                client.close();
            }
        }
    }
    static class LinkWriter extends PrintWriter {
        ByteArrayOutputStream buffer;
        Writer client;
        LinkWriter(Writer client, ByteArrayOutputStream buffer) {
            super(buffer);
            this.buffer = buffer;
            this.client = client;
        }
        public void close() {
            try {
                flush();
                client.write(linkText(buffer.toString()));
                client.close();
            } catch (IOException e) {
                setError();
            }
        }
        String  linkText(String text) {
            text = text.replaceAll( "resourceType", "None");//BOOK HAS DIFFERENT LOGIC
            return text;
        }
    }
}
java servlet-filters hapi-fhir
1个回答
0
投票

书本身明确提到了

这比我们之前的示例稍长一些,但基本原理是相同的。我们使用 HttpServletResponseWrapper 帮助器类用我们自己的 WrappedResponse 类包装 HttpServletResponse 对象。我们的 WrappedResponse 重写了两个方法:getWriter() 和 setContentType()。我们重写 setContentType() 以设置一个标志来指示输出是否为“text/html”类型(HTML 文档)。例如,我们不想对图像等二进制数据执行正则表达式替换,因为它们恰好与我们的过滤器匹配。我们还重写 getWriter() 以提供替代写入器流 LinkWriter。我们的 LinkWriter 类是一个 PrintStream,它以客户端 PrintWriter 和一个 ByteArrayOutputStream 作为参数,该 ByteArrayOutputStream 用作在写入之前存储输出数据的缓冲区。仅当 setContent() 设置的 linkText 布尔值为 true 时,我们才会小心地替换 LinkWriter。当我们使用 LinkWriter 时,我们会缓存该流,以便对 getWriter() 的任何后续调用都返回相同的对象。最后,我们向响应对象添加了一种方法:close()。普通的 HttpServletResponse 没有 close() 方法。我们在返回客户端时使用我们的值来指示 LinkWriter 应该完成其处理并将实际数据写入客户端。我们这样做是为了防止客户端在退出 servlet 服务方法之前没有显式关闭输出流。

这意味着当我们为 contentType

linkText = true
设置
"application/fhir+json"
时,
getWriter()
方法将返回相同的对象,这意味着 WrappedResponse 不会发生在具有 contentType
"application/fhir+json"
的成功响应中。

正如我之前问的,您是否经历过调试模式的成功和失败。

  1. 失败异常的标志也设置为 true 吗?
  2. 您还有其他过滤器配置吗
  3. linkText
    是您案件的罪魁祸首。调试一下你就会得出结论
© www.soinside.com 2019 - 2024. All rights reserved.