如何处理ServerSOAPFaultException?它与SOAPFaultException的处理有何不同?
SOAPFaultException vs ServerSOAPFaultException:区别与处理方案
嘿,我来帮你把这两个异常的区别掰扯清楚,再说说怎么处理ServerSOAPFaultException——毕竟之前做WebService集成的时候,我也踩过类似的坑,太懂这种摸不着头脑的感觉了!
核心区别:通用父类 vs 服务端专属子类
这俩本质上是父子关系,但定位和使用场景完全不一样:
- SOAPFaultException:这是JAX-WS标准API定义的通用异常(属于
javax.xml.ws.soap包),是所有SOAP Fault场景的"兜底"异常。不管是客户端请求格式出错,还是服务端业务逻辑报错,只要收到了SOAP Fault消息,底层框架都会先封装成这个类。 - ServerSOAPFaultException:这是Sun/Oracle的JAX-WS参考实现(就是你用的
com.sun.xml.internal.ws这套)特有的子类(属于com.sun.xml.internal.ws.fault包)。它专门用来标记服务端主动返回的SOAP Fault——比如你遇到的会话超时,就是服务端检测到会话失效后主动抛出的Fault,底层实现会把通用的SOAPFaultException进一步包装成这个子类,帮你精准定位异常来自服务端。
简单总结:ServerSOAPFaultException是SOAPFaultException的"服务端专属定制版",是特定JAX-WS实现的扩展类。
如何处理ServerSOAPFaultException?
处理思路和你处理SOAPFaultException基本一致,甚至更灵活,给你两种实用方案:
方案1:精准捕获子类(针对性处理服务端Fault)
如果你只想聚焦处理服务端返回的错误,可以直接捕获ServerSOAPFaultException,然后提取Fault里的细节做针对性处理:
try { // 调用第三方WebService的业务代码 } catch (ServerSOAPFaultException e) { // 获取SOAP Fault的详细信息 SOAPFault fault = e.getFault(); String faultCode = fault.getFaultCode(); String faultMessage = fault.getFaultString(); // 针对会话超时场景做处理:比如刷新会话后重试 if (faultMessage.contains("session has timed-out")) { refreshSession(); // 你的会话刷新逻辑 retryWebServiceCall(); // 重试调用(建议加重试次数限制) } else { // 处理其他服务端Fault,比如记录日志、告警等 log.error("服务端返回SOAP Fault: {}", faultMessage, e); notifyAdmin(fault); } } catch (SOAPFaultException e) { // 处理客户端侧的SOAP Fault,比如请求格式错误、参数非法等 handleClientSideFaults(e); }
方案2:统一捕获父类(兼容所有场景,保证可移植性)
因为ServerSOAPFaultException是特定JAX-WS实现的类,如果你未来切换到Apache CXF这类其他实现,这个类就不存在了。所以更推荐统一捕获标准的SOAPFaultException,再通过类型判断或Fault内容区分场景:
try { // 调用第三方WebService的业务代码 } catch (SOAPFaultException e) { SOAPFault fault = e.getFault(); String faultMessage = fault.getFaultString(); if (e instanceof ServerSOAPFaultException) { // 服务端返回的Fault,比如会话超时 if (faultMessage.contains("session has timed-out")) { refreshSession(); retryWebServiceCall(); } } else { // 客户端侧的SOAP Fault log.warn("客户端请求引发SOAP Fault: {}", faultMessage, e); validateRequestParams(); } }
额外提醒:别依赖内部类的细节
com.sun.xml.internal.ws下的类都是JDK内部实现,不属于标准API,未来可能会有变动。所以尽量通过SOAP Fault的内容(比如faultString、faultCode)来判断场景,而不是依赖ServerSOAPFaultException这个类本身,这样代码更稳定、更易迁移。
你提供的异常栈信息
com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Your session has timed-out. Please see the server log to find more detail regarding exact cause of the failure. com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:178) com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:116) com.sun.xml.internal.ws.client.sei.StubHandler.readResponse(StubHandler.java:238) com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:189) com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:276) com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:104) com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77) com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147)
内容的提问来源于stack exchange,提问作者Sagar Pudi
相关产品推荐
相关产品推荐

