Servlets 在servlet筛选器中创建错误页会导致错误“;作者已获得;

Servlets 在servlet筛选器中创建错误页会导致错误“;作者已获得;,servlets,servlet-filters,custom-error-pages,Servlets,Servlet Filters,Custom Error Pages,我正在为众多JSF1.x和2.x应用程序创建一个自定义框架(类似于门户)。为此,我创建了一个servlet过滤器,该过滤器使用框架菜单、面包屑、注销等“丰富”应用程序HTML。在该过滤器中,我读取应用程序的HTML,修改它并将其写入输出流。到目前为止,一切都很好,但现在我在创建自定义错误页面方面遇到了问题 我尝试读取响应状态代码,并根据该代码创建输出HTML: public void doFilter(ServletRequest req, ServletResponse resp, Filte

我正在为众多JSF1.x和2.x应用程序创建一个自定义框架(类似于门户)。为此,我创建了一个servlet过滤器,该过滤器使用框架菜单、面包屑、注销等“丰富”应用程序HTML。在该过滤器中,我读取应用程序的HTML,修改它并将其写入输出流。到目前为止,一切都很好,但现在我在创建自定义错误页面方面遇到了问题

我尝试读取响应状态代码,并根据该代码创建输出HTML:

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    HttpServletRequest req = (HttpServletRequest) req;
    HttpServletResponse res = (HttpServletResponse) resp;
    StringServletResponseWrapper responseWrapper = new StringServletResponseWrapper(res);
    // Invoke resource, accumulating output in the wrapper.
    chain.doFilter(req, responseWrapper);
    String contentType = res.getContentType();
    byte[] data;
    if (contentType.contains("text/html")) {
        String html = null;
        int statusCode = res.getStatus();
        LOG.debug("status: {}, committed: {}", statusCode, res.isCommitted());

        if (statusCode != 200) {
            html = "<!DOCTYPE html>\r\n" +
                    "<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n" +
                    "<head>\r\n" +
                    "<script type=\"text/javascript\" src=\"/path/to/jquery/jquery-1.11.1.min.js\"></script>\r\n" +
                    "<title>Error</title>\r\n" +
                    "</head>\r\n" +
                    "<body>\r\n" +
                    "<h1>Error</h1>\r\n" +
                    "</body>\r\n" +
                    "</html>";
            Collection<String> headerNames = res.getHeaderNames();
            Map<String, String> headerMap = new HashMap<String, String>();
            for (String header : headerNames) {
                headerMap.put(header, res.getHeader(header));
            }
            res.reset();
            for (Map.Entry<String,String> entry : headerMap.entrySet()) {
                res.setHeader(entry.getKey(), entry.getValue());
            }
            res.setStatus(statusCode);
            response.setContentType("text/html");
        } else {
            html = responseWrapper.getCaptureAsString();
        }

        if (ObjectUtils.isNotEmpty(html)) {
            // do some modification
            String modifiedResponse = doModification(html);
            data = modifiedResponse.getBytes("UTF-8");
            response.setContentLength(data.length);
            response.getOutputStream().write(data); // this line causes error
        }
    } else {
        data = responseWrapper.getCaptureAsBytes();
        response.setContentLength(data.length);
        response.getOutputStream().write(data);
    }
}
我真的不明白为什么会出现这个错误。两种情况之间的唯一区别是HTML内容,它在两种情况下都是有效的。有什么帮助吗

使用WebSphereApplicationServer8.5.5.18

编辑:我尝试调用
reset()
,然后再次设置标题和状态代码,但是
reset()
调用会导致
IllegalStateException
——正如javadoc中所述,显然响应已经提交。据我所知,
ServletOutputStream
flush()
方法可能会导致提交响应,但我不会在任何地方调用它。我还添加了一些日志,以查看响应是否确实已提交。在这两种情况下(状态200和404)
response.isCommitted()
返回true。这是否意味着在调用doFilter之前提交响应

com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[Faces Servlet]: java.lang.IllegalStateException: SRVE0209E: Writer already obtained