Apache CXF/MTOM在通过Weblogic 12c运行时会损坏文件

Apache CXF/MTOM在通过Weblogic 12c运行时会损坏文件,apache,weblogic,cxf,corruption,mtom,Apache,Weblogic,Cxf,Corruption,Mtom,我正在运行一个基于CXF的web服务客户端(使用.net端的web服务)。除了pdf文件传输之外,其他方法都能很好地工作 如果我通过junit(spring loaded context和cxf)运行相同的配置,或者通过soap ui使用相同的web服务,则pdf文件传输正确 一旦我通过WebLogic12c(12.1.3)运行它,pdf的二进制内容就会损坏。下面是一个例子: * Good File (transferred via CXF standalone / junit) * %PDF

我正在运行一个基于CXF的web服务客户端(使用.net端的web服务)。除了pdf文件传输之外,其他方法都能很好地工作

如果我通过junit(spring loaded context和cxf)运行相同的配置,或者通过soap ui使用相同的web服务,则pdf文件传输正确

一旦我通过WebLogic12c(12.1.3)运行它,pdf的二进制内容就会损坏。下面是一个例子:

* Good File (transferred via CXF standalone / junit) * 
%PDF-1.3 
1 0 obj 
[/PDF /Text /ImageB /ImageC /ImageI] 
endobj 
9 0 obj 
<< /Length 1659 /Filter /FlateDecode >> stream 
xœXÛnÛ8}_ 

* Bad File (transferred via WLS/CXF) * 
%PDF-1.3 
1 0 obj 
[/PDF /Text /ImageB /ImageC /ImageI] 
endobj 
9 0 obj 
<< /Length 1659 /Filter /FlateDecode >> stream 
xœ�XÛnÛ8}_ 
*良好的文件(通过CXF standalone/junit传输)*
%PDF-1.3
10 obj
[/PDF/Text/ImageB/ImageC/ImageI]
endobj
9.0 obj
>溪流
xœxÛnÛ8}
*错误文件(通过WLS/CXF传输)*
%PDF-1.3
10 obj
[/PDF/Text/ImageB/ImageC/ImageI]
endobj
9.0 obj
>溪流
xœ�XÛnÛ8}
您可以看到stream部分在那里获得了一个额外的字节(这只是文件的开始…额外的字节在后面显示了很多次)。运行这一个windows或linux将导致传输损坏。爪哇8。CXF 2.7和3.1

我仍在调查这个问题,但如果您有任何想法,我们将不胜感激

  • 是否需要在某个地方设置/取消设置编码
  • 是否应该使用web模块上的一些首选库
  • 可能只是缺少应用程序服务器补丁-

正如我在评论中解释的那样,导致损坏的罪魁祸首是一个自定义日志处理程序,它作为传入消息拦截器被注入。它用UTF-8编码整个消息,包括二进制内容

Client client = ClientProxy.getClient(port);
client.getInInteceptors().add(inLogger);
但是,我还没有找到为什么这个日志记录器没有在weblogic容器之外引起问题。与Oracle支持人员交谈没有多大帮助,因为他们希望我提交一个可运行的测试用例来复制问题。。。这几乎是不可能的(即web服务由另一家公司托管)

我还想提到一种在消息管道启动之前轻松处理消息的方法。只需将自定义消息观察者注入端点即可。像这样:

Endpoint endpoint = client.getEndpoint();
HTTPConduit conduit = (HTTPConduit) client.getConduit();
conduit.setMessageObserver(new MyMessageObserver(client));
请记住,在处理消息内容时,输入流在被使用后总是必须重置(一种或另一种方式)。在message observer中,您可能希望保存消息内容,然后将其传递并在返回时重置。按照这些思路:

@Override public void onMessage(Message message) {
    InputStream is = message.getContent(InputStream.class);
    InputStream mis = save(is);
    is.reset();
    client.onMessage(message);
    message.setContent(InputStream.class, mis);
}
其他明显的消息处理程序注入是通过In/outiterceptors()完成的,如果查看管道,可以根据定义的消息处理阶段将它们注入任何位置。。接收、预流等。。。根据这些将是管道的一部分,但在客户介入之后。MyMessageObserver位于管道之前


希望这有助于Apache CXF调试…

WLS/CXF和CXF standalone/junit的版本是否相同?是的。上一次测试的CXF 3.1.0。结果表明,其中一个(自定义)传入消息拦截器已将整个消息编码为UTF-8。包括mtom附件的二进制内容。此拦截器一直充当传入消息记录器:Client.clientProxy(port.getInInterceptors().add(inLogger);在我们开始接收saaj消息之前,这一切都很顺利。在日志处理程序中重新编写代码非常简单。然而,当消息在Weblogic容器之外接收时,为什么这对消息没有影响仍然是个谜。关于这一点没有任何线索。另外一个保持原始消息的简单解决方法是通过向端点添加消息观察者来添加另一个(起始)消息拦截器。通常的起始观察者(调用管道)是实际的ClientImpl。因此,endpoint.addObserver(myObserver)可以保留原始消息,直到管道完成。保存消息,然后呼叫客户端。Buhh。。。这件事我花了两天时间。问题是,我在端口上附加了一个日志处理程序。我的调查更糟。。。它在一个Weblogic上工作,但在另一个Weblogic上不工作(相同的版本)。它还在进行frm单元测试。你能把你的发现写进答案里,这样我就可以奖励你一笔赏金吗?