JAX-WS – 映射故障的例外

我正在使用JAX WS来公开WebService。 此服务的某些操作可能会生成exception。 不是内部服务器exception,而是依赖于操作调用的输入参数的exception。

如果我指定我的操作抛出自定义exception,如下所示:

@WebService @SOAPBinding(style = Style.RPC, use = Use.LITERAL) public class MyServiceEndpointImpl implements MyServiceEndpoint { @WebMethod public void throwsException throws InvalidInputException; } 

运行应用程序时,我最终得到以下堆栈跟踪:

  com.sun.xml.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class com.mypackage.ws.services.jaxws.InvalidInputExceptionBean is not found. Have you run APT to generate them? at com.sun.xml.ws.model.RuntimeModeler.getClass(RuntimeModeler.java:285) at com.sun.xml.ws.model.RuntimeModeler.processExceptions(RuntimeModeler.java:1006) at com.sun.xml.ws.model.RuntimeModeler.processRpcMethod(RuntimeModeler.java:969) at com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:546) at com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:370) at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:256) at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:322) at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:188) at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:467) at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:333) at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:45) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport$1.run(FactoryBeanRegistrySupport.java:121) 

@XmlRootEntity添加到InvalidInputException并不能解决问题。

如果这不是报告Web服务故障的推荐方法,那么有更好的方法吗? 我的exception是否应该从RuntimeExceptioninheritance并依赖于传输来进行error handling(即,所有内容最终都将包含在SOAPException中)? 我希望有类似Spring-WS的SoapFaultAnnotationExceptionResolver 。 是否有类似JAX-WS的类似内容?

您是否尝试使用@WebFault注释您的exception? 另外,你实现了getFaultInfo()吗?

编辑:我意识到我的答案可能不够详细。 正如在这个post中提醒的那样(例如):

JAX-WS 2.0规范要求使用@WebFault注释的exception必须具有两个构造函数和一个方法[获取故障信息的getter]:

 WrapperException(String message, FaultBean faultInfo) WrapperException(String message, FaultBean faultInfo, Throwable cause) FaultBean getFaultInfo() 

WrapperException被exception的名称替换, FaultBean被实现故障bean的类名替换。 故障bean是一个Java bean,它包含故障信息,并由Web服务客户端用于了解故障原因。

这在JAX-WS规范的2.5故障中有详细说明。 你的例外符合这个吗? 你可以发布代码吗?


OP是对的。 根据规范2.1,第3.7节“服务特定exception”,不需要使用@WebFault批注,JAX-WS可以动态生成包装bean,用于与2.5节中描述的模式不匹配的exception(只需提供一个getter用于您希望出现在故障中的信息)。 对于与第2.5节中描述的模式匹配的exception(即具有@WebFault方法和@WebFault批注的exception),在将exception映射到XML Schema时, FaultBean用作JAXB的输入。

因此,上面建议的解决方案(匹配2.5节中描述的模式)只是一种解决方法。 包装bean的生成应该适用于其他exception。 我不知道为什么这会失败。

上面的答案的补充。 我最终将此作为我的InvalidInputException实现:

 @WebFault(faultBean = "com.mypackage.ws.exception.FaultBean") public class InvalidInputException extends Exception { private static final long serialVersionUID = 1L; private FaultBean faultBean; public InvalidInputException() { super(); } public InvalidInputException(String message, FaultBean faultBean, Throwable cause) { super(message, cause); this.faultBean = faultBean; } public InvalidInputException(String message, FaultBean faultBean) { super(message); this.faultBean = faultBean; } public FaultBean getFaultInfo() { return faultBean; } } 

FaultBean只是一个简单的POJO,目前根本没有数据。 现在,根据JAX-WS规范(参见3.7 Service Specific Exception),它符合使用@WebFault注释的exception的要求,因此它不会为它创建一个包装bean,这可能是失败的。

这是一个不错的解决方法,但它没有解释问题中的错误。