JAX-WS - 将异常映射到故障

2022-09-01 14:18:31

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

如果我指定我的操作会引发自定义异常,如下所示:

@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)

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

如果这不是通过Web服务报告故障的推荐方法,那么是否有更好的方法?我的异常是否应该继承并依赖于错误处理的传输(即,所有内容最终都将包装在SOAPException中)?我希望能有类似Spring-WS'的东西。JAX-WS 是否有类似的东西可用?RuntimeExceptionSoapFaultAnnotationExceptionResolver


答案 1

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

编辑:我意识到我的答案可能不够详细。如此线程中所述(例如):

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

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

将替换为异常的名称,并替换为实现故障 Bean 的类名。故障 Bean 是一个 Java Bean,它包含故障信息,Web 服务客户端使用它来了解故障原因。WrapperExceptionFaultBean

JAX-WS 规范的 2.5 节故障中对此进行了详细介绍。您的例外是否符合此条件?您可以发布代码吗?


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

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


答案 2

对上述答案的补充。我最终以这个作为我的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;
    }
}

并且只是一个简单的POJO,目前根本没有数据。现在,根据 JAX-WS 规范(参见 3.7 服务特定异常),它符合用 @WebFault 注释的异常的要求,因此它不会为其创建包装器 Bean,这可能是失败的原因。FaultBean

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


推荐