本文介绍了返回错误的JAX-WS服务器端SOAPHandler会收到“内部错误"消息.在WebSphere v8上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个服务器端JAX-WS SOAPHandler(在WebSphere v8上),在某些情况下,它需要使用String变量中的SOAP响应来响应客户机(我们称之为responseXml).

I have a server-side JAX-WS SOAPHandler (on WebSphere v8) that in certain cases needs to respond to the client with a SOAP response that it has in a String variable (let's call it responseXml).

responseXml包含成功的(即,非故障的)SOAP消息时,JAX-WS将响应正确发送到客户端.但是,当responseXml包含SOAP错误消息时,将发生内部错误",并且客户端将获得与responseXml中的错误响应不同的错误响应,如下所示:

When responseXml contains a successful (i.e., non-fault) SOAP message, JAX-WS sends the response to the client correctly. However, when responseXml contains a SOAP fault message, an "Internal Error" occurs, and the client gets a different fault response than the one in responseXml, as shown here:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <soapenv:Fault xmlns:axis2ns1="http://schemas.xmlsoap.org/soap/envelope/">
         <faultcode>axis2ns1:Server</faultcode>
         <faultstring>Internal Error</faultstring>
         <detail/>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

以下错误被写入控制台:

The following error is written to the console:

[10/9/12 12:21:04:177 EDT] 00000025 AxisEngine    E org.apache.axis2.engine.AxisEngine receive An error was detected during JAXWS processing
                             org.apache.axis2.AxisFault: An error was detected during JAXWS processing
at org.apache.axis2.jaxws.server.JAXWSMessageReceiver.receive(JAXWSMessageReceiver.java:208)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:198)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
at com.ibm.ws.websvcs.transport.http.WASAxis2Servlet.doPost(WASAxis2Servlet.java:1466)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
...

这是一个简化的SOAPHandler,它说明了此问题. (请注意,此处显示的responseXml的值只是一个示例.在我的实际SOAPHandler中,响应不是硬编码的,而是从数据库中读取的.我只是在尝试显示尽可能简单的示例代码. )

Here is a simplified SOAPHandler that illustrates this problem. (Note that the value of responseXml shown here is just an example. In my actual SOAPHandler, the responses are not hard-coded but are read from a database. I'm just trying to show the simplest sample code possible.)

package simplified.demo;

import java.io.ByteArrayInputStream;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class FaultyHandler implements SOAPHandler<SOAPMessageContext> {

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (!outbound) {
            String responseXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header></soapenv:Header><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server</faultcode><faultstring>ORA-01031: insufficient privileges</faultstring><detail/></soapenv:Fault></soapenv:Body></soapenv:Envelope>";
            try {
                SOAPMessage newMsg = createSOAPMessage(responseXml);
                context.setMessage(newMsg);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        return (outbound);
    }

    private SOAPMessage createSOAPMessage(String responseXml) {
        try {
            ByteArrayInputStream in = new ByteArrayInputStream(responseXml.getBytes());
            MessageFactory messageFactory = MessageFactory.newInstance();
            return messageFactory.createMessage(null, in);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return true;
    }

    @Override
    public Set<QName> getHeaders() {
        return null;
    }

    @Override
    public void close(MessageContext context) {
    }
}

当我对SOAPHandler进行编码以创建SOAPFault对象(使用SOAPFactory)并将其扔到SOAPFaultException中时,会得到完全相同的错误.

I get the exact same error when I code the SOAPHandler to create a SOAPFault object (using a SOAPFactory) and throw it in a SOAPFaultException.

基于堆栈跟踪,我查看了 JAXWSMessageReceiver ,看起来Axis2在寻找幕后原因,但当然在这种情况下没有一个.

Based on the stack trace, I looked at the source code for JAXWSMessageReceiver, and it looks like under the covers, Axis2 is looking for a causedByException, but of course in this case there isn't one.

有人知道为什么会这样或如何解决吗?谢谢!

Does anyone know why this is happening or how it can be fixed? Thanks!

推荐答案

我遇到了同样的问题,并且能够通过禁用统一的错误处理来解决此问题(这不是错误,它是一个功能!).

I had the same problem and was able to solve it by disabling the unified fault handling (it's not a bug, it's a feature!).

在WAS开发人员控制台上

On the WAS Developer console

https://<yourhost>/<yourport>/ibm/console/login.do

按照此处(适用于WAS8):

do as described here (for WAS8):

在那里,添加一个新属性webservices.unify.faults并将其值设置为false.

There, add a new property webservices.unify.faults and set the value to false.

这篇关于返回错误的JAX-WS服务器端SOAPHandler会收到“内部错误"消息.在WebSphere v8上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 03:58
查看更多