Java Spring Web服务客户端故障处理

问题描述:

我编写了一个与UPS Web服务配合使用的Web服务客户端(使用Java Spring和JAXB Marshaller)。当我发送有效请求时,一切正常。当我发送无效请求(重量> 150磅)时,UPS Web服务会响应SOAP Fault。客户端应用程序失败了

I have written a web service client (using Java Spring and JAXB Marshaller) that works with the UPS web service. When I send a valid request everything works well. When I send an invalid request (weight > 150 lbs) then the UPS web service responds with a SOAP Fault. The client application just fails with a

org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling 
exception; nested exception is javax.xml.bind.UnmarshalException: 
unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Fault").

显然我的程序无法破译Web服务返回的SOAP错误。我写了一个自定义的FaultMessageResolver,但它没有被调用。这是代码:

Obviously my program isn't able to decipher the SOAP fault returned by the web service. I wrote a custom FaultMessageResolver, but it doesn't get invoked. Here's the code:

public class UpsRateClient extends WebServiceGatewaySupport {
    public UpsRateClient(WebServiceMessageFactory messageFactory) {
        super(messageFactory);
        getWebServiceTemplate().setFaultMessageResolver(new UpsFaultMessageResolver());
    }

    public RateResponse getRate(RateRequest rateRequest) {
        return (RateResponse) getWebServiceTemplate().marshalSendAndReceive(rateRequest, new UpsRequestWSMC());
    }
    private class UpsFaultMessageResolver implements FaultMessageResolver {
        public void resolveFault(WebServiceMessage message) throws IOException{
            System.out.println("Inside UpsFaultMessageResolver");   
        }
    }
}

感谢您的时间!

采取wirehark跟踪。我想是也许Web服务使用(错误)发送SOAP错误>)HTTP 200OK而不是500内部服务器错误,您的客户端尝试将其作为有效响应处理。

如果是这种情况那么问题在于Web服务没有加入到SOAP标准(我的重点):

来自 SOAP RFC

Take a wireshark trace.My thought is that perhaps the web service sends the SOAP fault using (erroneously) a HTTP 200OK instead of a 500 Internal Server error and your client tries to handle it as a valid response.
If this is the case this is then the problem lies in the web service which does not addere to SOAP standard(my emphasis):
From SOAP RFC


如果在处理请求时出现SOAP错误,则为SOAP HTTP
服务器务必发出HTTP 500内部服务器错误响应
在响应中包含一条SOAP消息,其中包含SOAP Fault元素
(参见第4.4节),指示SOAP处理错误。

In case of a SOAP error while processing the request, the SOAP HTTP server MUST issue an HTTP 500 "Internal Server Error" response and include a SOAP message in the response containing a SOAP Fault element (see section 4.4) indicating the SOAP processing error.

如果你不拥有网络服务,他们应该解决这个问题。

老实说我不确定Spring-WS中的工作是什么。

如果我真的需要在Jax-Ws中工作,我会用 Dispatcher 自己处理原始xml并避免自动编组/ demarhal。

如果你能做同样的话,看看Spring-Ws,但这是网络服务的错误,而不是你的客户

If you do not own the web service, they should fix this.
To be honest I am not sure what the work arround would be in Spring-WS.
If I really needed a work arround in Jax-Ws I would replace the stub call with a Dispatcher to handle the raw xml myself and avoid the automatic marshal/demarhal.
Look into Spring-Ws if you can do the same, but this is a bug of the web service, not your client