Exception 发送大soap请求时发生异常
Tomcat6上部署了一个web服务,并通过ApacheCXF2.3.3公开。生成的源代码使用wsdl2java存根来调用此服务 在我发出~1Mb的大请求之前,一切似乎都很好。未处理此请求,失败,出现异常:Exception 发送大soap请求时发生异常,exception,soap,wsdl,cxf,wsdl2java,Exception,Soap,Wsdl,Cxf,Wsdl2java,Tomcat6上部署了一个web服务,并通过ApacheCXF2.3.3公开。生成的源代码使用wsdl2java存根来调用此服务 在我发出~1Mb的大请求之前,一切似乎都很好。未处理此请求,失败,出现异常: Interceptor for {http://localhost/}ResourceAllocationServiceSoapService has thrown exception, unwinding now org.apache.cxf.binding.soap.Soap
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]
这里是某种最大请求长度,我完全被它卡住了。我找到了问题所在。实际上,这是拦截器代码中的错误:
CachedOutputStream requestStream = new CachedOutputStream()
当我把这个换成
CachedOutputStream requestStream = new CachedOutputStream(1000000);
事情开始进展顺利
因此,在复制流的过程中,请求只是集群化了。成功了。下面的代码将帮助其他人理解将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());
*/
}
}
我遇到了geting com.ctc.wstx.exc.WstxEOFException的相同问题:在使用CachedOutputStream类时,prolog中出现了意外的EOF 查看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您在何处添加此CachedOutStream requestStream=new CachedOutStream1000000;看,我也面临着同样的问题