【发布时间】:2023-03-26 20:31:01
【问题描述】:
我在 CXF 方面遇到了一个非常棘手的问题,我试图解决(不成功)一个多月。我读过很多类似的问题,但没有任何帮助。
首先介绍一下我用来保存出站消息的部分代码:
public void handleMessage(SoapMessage message) throws Fault {
OutputStream os = message.getContent(OutputStream.class);
CacheAndWriteOutputStream cwos = new CacheAndWriteOutputStream(os);
message.setContent(OutputStream.class, cwos);
cwos.registerCallback(new LoggingOutCallBack());
}
class LoggingOutCallBack implements CachedOutputStreamCallback
{
public void onClose (CachedOutputStream cos)
{
try
{
String result = IOUtils.toString(cos.getInputStream());
}
catch (Exception e)
{
LogFactory.getLog(SwcFinalResponseInterceptor.class).error(ExceptionUtils.getStackTrace(e));
}
}
public void onFlush (CachedOutputStream arg)
{
}
}
我使用 PRE_STREAM 阶段。很多地方都提到了这种方法(例如,here),但它会导致一些罕见的错误。我每天大约有 20000 个请求,所以,比如说,对于 200 个大请求,这种方法失败了 - 对于进一步的请求之一,我得到 Stream closed 错误。
2013-12-19 15:37:47,902 [WARN ] org.apache.cxf.common.logging.LogUtils.doLog(LogUtils.java:400)
5880162-Interceptor for {http://service.ws.swc.comtech/}FrequentFlyerServiceWsService has thrown exception, unwinding now
5880163-org.apache.cxf.interceptor.Fault: Stream closed
5880164- at org.apache.cxf.interceptor.LoggingInInterceptor.logging(LoggingInInterceptor.java:144)
5880165- at org.apache.cxf.interceptor.LoggingInInterceptor.handleMessage(LoggingInInterceptor.java:73)
我绝对确定这是因为我的代码中的这一行:
cos.getInputStream()
我已经测试了很多次,没有这一行,一切正常,但是当我添加这一行时,错误立即出现。 我想这是因为 CXF 不是在内存中而是在某个临时文件中存储大流的流数据。它被描述为here。
有趣的一点是,当我尝试自己加载测试服务器时,使用 curl 发送数千个繁重的请求,没有错误,但是当有很多客户端时,几乎立即开始出现问题。
我还找到了another solution,乍一看,它似乎工作正常,我不再收到
Stream closed错误,但服务器开始跳过一些响应。
请帮帮我,我真的不知道我还能读什么或做什么,我不擅长流和 CXF,但我需要一个可行的解决方案,如果你能解释我做错了什么,那就太好了。
如果您不能直接回答这个问题,请至少回答以下一些问题:
为什么需要这一行message.setContent(OutputStream.class, cwos);? 我不想修改流内容,只是获取里面的内容,那我为什么要读取然后再次发送内容?
可能有比这个 message.getContent(OutputStream.class); 更合适的格式(要获取的类)?
我应该使用另一个拦截器阶段吗?
有一个方法onClose,在流关闭之前或之后触发?这什么时候发生?我不希望在它的内容作为请求发送给客户端之前关闭它。
提前致谢!
【问题讨论】:
-
你是用spring来配置cxf的吗
-
嗯,我不知道,因为项目是在我之前编写的。据我判断,它使用名为 appContext.xml 的 XML 文件进行配置。