如何在Java中使用过滤器输出基于HTML文档的二进制文档

如何在Java中使用过滤器输出基于HTML文档的二进制文档,java,image,servlets,httpresponse,servlet-filters,Java,Image,Servlets,Httpresponse,Servlet Filters,这可能有点混乱,但我遇到了一些麻烦。我的目标是获取一个输入HTML文档,然后处理该文档并使用HTML数据输出一个图像文档。例如,用户将请求URL,查询字符串中的some action=png,然后将为URL和输出图像文档调用过滤器 我尝试了所有方法,但在我的环境(Websphere)中,我只能输出一种类型的输出。如果输入类型是text/html,那么我只能输出一个文本文档,而不能输出二进制文档。为什么?因为我每次都会得到一个非法的状态异常 [1/29/09 17:59:57:576 EST]00

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

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

[1/29/09 17:59:57:576 EST]00000020 SystemErr R java.lang.IllegalStateException:SRVE0209E:已获得写入程序 [1/29/09 17:59:57:576 EST]00000020 SystemErr R位于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 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()

我没有使用Websphere的经验,但一个常见的问题是,在您已经承诺发送正文之后,您尝试操作HTTP标头——一旦Web服务器开始交付内容,您就无法再更新标头,因为它们已经被发送

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

干杯,
Volker

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

看起来您应该能够做到:

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

您肯定无法安全地同时打开Writer和OutputStream

我想我可能已经找到了答案。我可以使用“response.getOutputstream”。但我有一段代码,浏览器不会重建页面,所以看起来我的响应为零。基本上,我的方法会奏效。你能解释一下为什么需要使用response.getWriter()吗?实际上,我可能有点迷茫。看起来这可能是WebSphere6.1/RAD7的一个bug。在response.getWriter()上,我认为我需要它,因为当我使用它时,代码工作正常。为什么要调用getWriter两次。只需调用getOutputStream并执行一次。“我的目标是获取一个输入HTML文档,然后处理该文档,并使用HTML数据输出一个图像文档。”--那么你的意思是要生成网页的图片?或者以其他方式处理HTML的内容以生成图像?还是描述错了?是的,我试过了。这就是我所认为的。但由于Websphere的某些原因,为了使事情正常工作,我必须在调用chain.doFilter(包装器)之前“打开打印编写器”。我想打印作者需要打开才能加入html内容。我最终使用了会话属性和重定向。因为我不会在同一个请求中“收集/加入”html内容。因此,我只是转发到一个简单的servlet,它依次输出二进制文件。这很奇怪,但它奏效了。
this.setFilterChain(filterChain);
CaptureContent capContent = new CaptureResponse(response);
doFilter()
process();
response.setContentType("image/png");
response.getOutputStream().write(imagedata);