【问题标题】:How to output a binary document based on a HTML document using filters in Java如何使用 Java 中的过滤器输出基于 HTML 文档的二进制文档
【发布时间】:2010-10-04 09:10:20
【问题描述】:

这可能有点令人困惑,但我遇到了一些麻烦。我的目标是获取输入的 HTML 文档,然后处理该文档并使用 HTML 数据输出图像文档。例如,用户将请求一个 URL,在查询字符串中包含一些 action=png,然后将为 URL 调用过滤器并输出图像文档。

我已经尝试了一切,但在我的环境(Websphere)中,我只能输出一种类型。如果输入类型是 text/html 那么我只能输出一个文本文档,我似乎不能输出一个二进制文档。为什么?因为我每次都得到一个非法的状态异常。

[1/29/09 17:59:57:576 EST] 00000020 SystemErr R java.lang.IllegalStateException: SRVE0209E: Writer 已获得 [1/29/09 17:59:57:576 EST] 00000020 SystemErr R at com.ibm.ws.webcontainer.srt.SRTServletResponse.getOutputStream(SRTServletResponse.java:505)

我使用伪代码来不泄露我的所有代码:

<filter>
    <filter-name>TestFilter</filter-name>
    <filter-class>
        com.util.TestFilter
    </filter-class>
</filter>

<filter-mapping>
    <filter-name>TestFilter</filter-name>
    <url-pattern>/index_test2.html</url-pattern>
</filter-mapping>

包装类代码本质上是这样的:

public class ContentCaptureServletResponse extends HttpServletResponseWrapper { 
    private ByteArrayOutputStream contentBuffer;
    private PrintWriter writer; 
    public PrintWriter getWriter() throws IOException {
        if (writer == null) {
            contentBuffer = new ByteArrayOutputStream();
            writer = new PrintWriter(contentBuffer);
        }       
        return writer;
    }   
    public String getContent(){
        try {
            writer = getWriter();
        } catch (IOException e) {           
            e.printStackTrace();
        }
        writer.flush();
        String xhtmlContent = new String(contentBuffer.toByteArray());                 
        System.out.println(xhtmlContent);                
        return xhtmlContent; 
    }
}

过滤代码是这样的:

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        final String renderType = request.getParameter("R"); 
        final String renderClassName = request.getParameter("C");
        if ((renderType != null) && (renderClassName != null)) {
            try {
                this.setFilterChain(filterChain);
                response.setContentType("image/png");
                PrintWriter out = response.getWriter();                             
                // I call getWriter but not BOTH!
                //response.getOutputStream();               
                response.getWriter();

                // Build up the HTML document into a string.
                    CaptureResponse capContent = new CaptureResponse(response);            
                this.mainFilterChain.doFilter(req, );
                String myString = capHtmlContent.getContent();

                // What I really want to do here is output an output stream
                // so I can write a binary image
                processStr(myString);
                response.getOutputStream();             
                response.write(binaryimage)

            } catch (Exception e) {            
                e.printStackTrace();
            }
            // No data will be output to the user.
        } else {
            filterChain.doFilter(request, response);
        }  // End of if-else        
    } // End of the method.

如果我想获取一些输入的 html 文本文档,该代码可以工作。我假设是因为打开了 printwriter 流。但是我在使用不同的格式时遇到了麻烦。基本上,因为我不能调用 response.getOutputStream()

【问题讨论】:

  • 我想我可能已经想通了。我可以使用“response.getOutputstream”。但是我有代码,浏览器不会重建页面,所以看起来我得到了零响应。基本上,我的方法会奏效。
  • 你能解释一下为什么需要使用 response.getWriter() 吗?
  • 其实我可能有点失落。看起来这可能是 Websphere 6.1/RAD7 的错误。在 response.getWriter() 上,我认为我需要它,因为当我使用它时,代码可以正常工作。
  • 你为什么要调用 getWriter 两次。只需调用一次 getOutputStream。
  • “我的目标是获取输入的 HTML 文档,然后处理该文档并使用 HTML 数据输出图像文档。” -- 所以你的意思是你想制作一个网页的图片?或者以其他方式处理 HTML 的内容来制作图像?还是描述有误?

标签: java image servlets httpresponse servlet-filters


【解决方案1】:

问题似乎是您在包装响应之前打开了响应编写器。

看起来你应该可以做到:

this.setFilterChain(filterChain);
CaptureContent capContent = new CaptureResponse(response);
doFilter()
process();
response.setContentType("image/png");
response.getOutputStream().write(imagedata);

您绝对不能安全地同时打开 Writer 和 OutputStream

【讨论】:

  • 是的,我试过了。这就是我所坚持的。但是由于 Websphere 的某些原因,为了让事情正常工作,我必须在调用 chain.doFilter(wrapper) 之前“打开打印编写器”。我想印刷作家需要打开才能加入 html 内容。我最终使用了会话属性和重定向。
  • 因为我不会在同一个请求中“收集/加入”html 内容。所以我只是转发到一个简单的servlet,然后输出二进制文件。这很奇怪,但确实有效。
【解决方案2】:

我没有使用 Websphere 的经验,但一个常见的问题是,您在已承诺发送正文后尝试操纵 HTTP 标头——一旦网络服务器开始传送内容,您将无法再更新标头,因为他们已经发送了。

也许您需要查看您的文档和示例。例如,我不明白你为什么在没有实际查看结果的情况下调用 response.get*() 。你确定这是必要的还是因为你修剪了你的代码?

干杯, 沃尔克

【讨论】:

    猜你喜欢
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 2011-08-23
    • 2021-06-29
    • 1970-01-01
    相关资源
    最近更新 更多