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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2064447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:08:56  来源:igfitidea点击:

JAX-WS - Map Exceptions to faults

javaweb-servicesjax-ws

提问by waxwing

I am using JAX WS to expose a WebService. Some of the operations of this service can generate exceptions. Not internal server exceptions, but rather exceptions that are dependent on the input arguments of the operation invocation.

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

If I specify that my operation throws a custom Exception, like so:

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

@WebService
@SOAPBinding(style = Style.RPC, use = Use.LITERAL)
public class MyServiceEndpointImpl implements MyServiceEndpoint {

    @WebMethod
    public void throwsException throws InvalidInputException;
}

I end up with the following stacktrace when running the application:

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

 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.run(FactoryBeanRegistrySupport.java:121)

Adding @XmlRootEntityto InvalidInputExceptiondoes not solve the problem.

添加@XmlRootEntityInvalidInputException不能解决问题。

If this is not the recommended way to report faults over web services, then is there a better way? Should my exceptions inherit from RuntimeExceptionand rely on the transport for the error handling (i.e., everything will end up wrapped in a SOAPException)? I was hoping for something like Spring-WS' SoapFaultAnnotationExceptionResolver. Is there something similar at all available for JAX-WS?

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

采纳答案by Pascal Thivent

Did you try to annotate your exception with @WebFault? Also, do you implement getFaultInfo()?

您是否尝试用 注释您的异常@WebFault?另外,你执行getFaultInfo()吗?

EDIT:I realize my answer was maybe not detailed enough. As reminded in this thread(for example):

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

The JAX-WS 2.0 specification demands that the exception annotated with @WebFaultmust have two constructors and one method [getter to obtain the fault information]:

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

The WrapperExceptionis replaced by the name of the exception, and FaultBeanis replaced by the class name that implements the fault bean. The fault bean is a Java bean that contains the information of the fault and is used by the Web service client to know the cause for the fault.

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

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

WrapperException由异常的名称取代, FaultBean由类名实现故障bean取代。故障 bean 是一个 Java bean,其中包含故障信息,供 Web 服务客户端用于了解故障原因。

This is detailed in section 2.5 Fault of the JAX-WS specification. Does your exception conform to this? Can you post the code?

这在 JAX-WS 规范的第 2.5 节故障中有详细说明。你的异常符合这个吗?你能把代码贴出来吗?



The OP is right. As per specification 2.1, section 3.7 Service Specific Exception, it is not required to use the @WebFaultannotation, JAX-WS can generate the wrapper beans dynamically for exceptions that do not match the pattern described in section 2.5 (just provide a getter for the information you want to be present in the fault). For exceptions that match the pattern described in section 2.5 (i.e. exceptions that have a getFaultInfomethod and @WebFaultannotation), the FaultBeanis used as input to JAXB when mapping the exception to XML Schema.

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

So the solution suggested above (matching the pattern described in section 2.5) is only a workaround. The generation of wrapper beans should just work for other exceptions. And I don't know why this fails here.

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

回答by waxwing

An addition to the answer above. I ended up with this as my InvalidInputException implementation:

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

And FaultBeanis just a simple POJO with currently no data at all. Now, according to the JAX-WS specification (see 3.7 Service Specific Exception), it conforms to what is required of an exception annotated with @WebFault, so it will not create a wrapper bean for it, which probably is what was failing.

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

This is a decent workaround, but it does not explain the error in the question.

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