如果 JAXWS 出现异常,如何发送自定义响应消息而不是故障消息?

How to send custom response message instead of Fault message in case of an exception with JAXWS?

在我的 JAXWS Web 服务中,我需要在发生异常时将特定消息发送回客户端,而不是带有异常描述的标准故障消息。

如何做到这一点?

我正在使用 jaxws-rt 版本 2.1.3

我已经尝试过像这样使用异常映射器但没有成功(有些方法没有调用它们,这也可能是配置错误引起的):

@Provider
public class ThrowableExceptionMapper implements ExceptionMapper<Throwable> {

    public ThrowableExceptionMapper() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public Response toResponse(Throwable throwable) {
        if (throwable instanceof WebApplicationException) {
            return ((WebApplicationException) throwable).getResponse();
        } else {
            return Response.serverError().entity("").build();
        }
    }
}

我们使用的服务器是JBoss EAP 6.4.

编辑:
异常映射器方法不适合我的 JAXWS Web 服务,因为它适用于 JAX-RS(感谢 SRINIVAS K)。 JAXWS 有类似的东西吗?

你可以尝试使用下面的方法吗?

String errorMessage = "this is custom error message";
return Response.status(e.getResponse().getStatus()).entity(errorMessage).build(); 

你能检查一下 ExceptionMapper 是否可以处理通用异常,比如 Throwable 或 Exception。
我看到一些使用 WebFault 注释配置自定义异常的示例。

我设法借助此页面重写了响应消息:
http://www.java-tips.org/java-ee-tips-100042/156-java-api-for-xml-web-services/1958-writing-a-handler-in-jax-ws.html

以及此页面的一些示例:
http://www.programcreek.com/java-api-examples/index.php?api=javax.xml.ws.handler.MessageContext

我整理了这个 class:

public class MyLogicalHandler implements LogicalHandler<LogicalMessageContext> {
    private final String RejectionResponseBody = "<ns2:MessageControllerResponse xmlns:ns2=\"http://some.namespace.com/\"><return>SOMEDATA</return></ns2:MessageControllerResponse>";

    @Override
    public boolean handleMessage(LogicalMessageContext context) {       
        return true;
    }

    @Override
    public boolean handleFault(LogicalMessageContext context) {
        processMessage(context);
        return true;
    }

    @Override
    public void close(MessageContext context) {

    }

    private void processMessage(LogicalMessageContext context) {
        Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (outboundProperty) {
            LogicalMessage msg = context.getMessage();
            msg.setPayload(new StreamSource(new ByteArrayInputStream(RejectionResponseBody.getBytes())));
        }
    }   
}

编辑,补充信息:

您还需要将 HandlerChain 注解添加到 Web 服务:

...
@HandlerChain(file = "handler-chain.xml")
public class MyWebService {
...
}

并创建处理程序链 xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">  
  <handler-chain>
    <handler>
      <handler-class>my.package.ws.jaxws.MyLogicalHandler</handler-class>
    </handler>
  </handler-chain>
</handler-chains>

并将此文件放在您的网络服务的资源文件夹中,您需要使用与网络服务相同的包结构。因此,如果您的 Web 服务 class 驻留在 my.package.ws 包中,则在资源文件夹中创建以下包:my.package.ws。