0

There is a web-service deployed on tomcat 6 and exposed via apache-cxf 2.3.3. A generated sources stubs using wsdl2java to be able to call this service.

Things seemed fine until I sent big request(~1Mb). This request wasn't processed and failing with exception:

Interceptor for {http://localhost/}ResourceAllocationServiceSoapService has thrown      
exception, unwinding now org.apache.cxf.binding.soap.SoapFault:
Error reading XMLStreamReader.
...
com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog 
at [row,col {unknown-source}]: [1,0]

Is some kind of max request length here, I'm totally stuck with it.

4

3 回答 3

3

弗拉基米尔的建议奏效了。下面的代码将帮助其他人了解将 1000000 放在哪里。

public void handleMessage(SoapMessage message) throws Fault { 
        // Get message content for dirty editing...

    InputStream inputStream = message.getContent(InputStream.class);

    if (inputStream != null)
    {
        String processedSoapEnv = "";
        // Cache InputStream so it can be read independently
        CachedOutputStream cachedInputStream = new CachedOutputStream(1000000);
        try {
            IOUtils.copy(inputStream,cachedInputStream);
            inputStream.close();
            cachedInputStream.close();

            InputStream tmpInputStream = cachedInputStream.getInputStream();
            try{
                String inputBuffer = "";
                int data;
                while((data = tmpInputStream.read()) != -1){
                    byte x = (byte)data;
                    inputBuffer += (char)x;
                }
                /**
                  * At this point you can choose to reformat the SOAP
                  * envelope or simply view it just make sure you put
                  * an InputStream back when you done (see below)
                  * otherwise CXF will complain.
                  */
                processedSoapEnv = fixSoapEnvelope(inputBuffer);
            }
            catch(IOException e){

            }
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        // Re-set the SOAP InputStream with the new envelope

        message.setContent(InputStream.class,new ByteArrayInputStream( processedSoapEnv.getBytes()));

        /**
         * If you just want to read the InputStream and not
         * modify it then you just need to put it back where
         * it was using the CXF cached inputstream
         *
         * message.setContent(InputStream.class,cachedInputStream.getInputStream());
        */
    }       


} 
于 2012-04-25T00:32:56.387 回答
2

我发现出了什么问题。实际上这是拦截器代码中的错误:

CachedOutputStream requestStream = new CachedOutputStream()

当我将其替换为

 CachedOutputStream requestStream = new CachedOutputStream(1000000);

事情开始正常了。

因此,该请求只是在复制流期间被中继。

于 2011-03-17T06:28:53.333 回答
2

在使用 CachedOutputStream 类时,我遇到了同样的问题,即“com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog”。

查看 CachedOutputStream 类的源,阈值用于在存储流的数据从“内存中”到“文件”之间切换。
假设流对超过阈值的数据进行操作,它将存储在文件中,因此以下代码将中断

IOUtils.copy(inputStream,cachedInputStream);
inputStream.close();
cachedInputStream.close(); //closes the stream, the file on disk gets deleted
InputStream tmpInputStream = cachedInputStream.getInputStream(); //returned tmpInputStream is brand *empty* one
// ... reading tmpInputStream here will produce WstxEOFException 

增加“阈值”确实有帮助,因为所有流数据都存储在内存中,在这种情况下调用 cachedInputStream.close() 并不会真正关闭底层流实现,因此以后仍然可以从中读取。

这是上述代码的“固定”版本(至少它对我来说无一例外)

IOUtils.copy(inputStream,cachedInputStream);
inputStream.close();
InputStream tmpInputStream = cachedInputStream.getInputStream();
cachedInputStream.close();
// reading from tmpInputStream here works fine

当在 tmpInputStream 上调用 close() 时临时文件被删除,并且没有其他对它的引用,请参阅 CachedOutputStream.maybeDeleteTempFile() 的源代码

于 2012-07-26T12:54:20.453 回答