如何在 JAX-WS Web 服务上引发自定义错误?

Posted

技术标签:

【中文标题】如何在 JAX-WS Web 服务上引发自定义错误?【英文标题】:How to throw a custom fault on a JAX-WS web service? 【发布时间】:2012-11-15 18:48:54 【问题描述】:

如何在 JAX-WS Web 服务上引发自定义的 soap 错误?如何指定肥皂故障的faultCodefaultStringdetail?是否可以将detail 的值设置为bean 而不是String

请注意,我正在使用代码优先方法进行开发。

【问题讨论】:

查看以下话题:[***.com/questions/15358204/…[1]:***.com/questions/15358204/… 【参考方案1】:

使用@WebFault 注释。

你可以在Using SOAP Faults and Exceptions in Java JAX-WS Web Services - Eben Hewitt on Java看到一个很好的例子。

你会看到这个例子:

@WebFault(name="CheckVerifyFault",
    targetNamespace="http://www.example.com")
public class CheckVerifyFault extends Exception 

    /**
     * Java type that goes as soapenv:Fault detail element.
     */
    private CheckFaultBean faultInfo;

    public CheckVerifyFault(String message, CheckFaultBean faultInfo) 
        super(message);
        this.faultInfo = faultInfo;
    

    public CheckVerifyFault(String message, CheckFaultBean faultInfo, 
           Throwable cause) 
        super(message, cause);
        this.faultInfo = faultInfo;
    

    public CheckFaultBean getFaultInfo() 
        return faultInfo;
    


更新

另一种方法是在throws 子句中声明典型异常

例如假设以下是我的异常类:

package pkg.ex;

public class FooException extends Exception 

    public FooException(String message, Throwable cause) 
        super(message, cause);
    


下一个类是服务实现。

package pkg.ws;

import javax.jws.WebService;
import pkg.ex.FooException;

@WebService(serviceName = "FooSvc")
public class FooService 

    public String sayHello(String name) throws FooException 
        if (name.isEmpty()) 
            Throwable t = new IllegalArgumentException("Empty name");
            throw new FooException("There is one error", t);
        
        return "Hello, " + name;
    


如果我的要求是:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                  xmlns:ws="http://ws.pkg/">
   <soapenv:Header/>
   <soapenv:Body>
      <ws:sayHello>
         <arg0>Peter</arg0>
      </ws:sayHello>
   </soapenv:Body>
</soapenv:Envelope>

没有问题:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <ns2:sayHelloResponse xmlns:ns2="http://ws.pkg/">
         <return>Hello, Peter</return>
      </ns2:sayHelloResponse>
   </S:Body>
</S:Envelope>

但是……

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                  xmlns:ws="http://ws.pkg/">
   <soapenv:Header/>
   <soapenv:Body>
      <ws:sayHello>
         <arg0></arg0>
      </ws:sayHello>
   </soapenv:Body>
</soapenv:Envelope>

那么……

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>S:Server</faultcode>
         <faultstring>There is one error</faultstring>
         <detail>
            <ns2:FooException xmlns:ns2="http://ws.pkg/">
               <message>There is one error</message>
            </ns2:FooException>
         </detail>
      </S:Fault>
   </S:Body>
</S:Envelope>

【讨论】:

嗨!感谢您的链接!得到它的工作。有没有办法让我也可以指定我的故障代码?如何使用上面的代码返回自定义的 faultCode?​​span> @Arci,我有同样的问题,除非您自己构造 SoapFaultException,否则这是不可能的。真正的废话! 使用@WebFault 我总是得到Marshalling Error: class my.test.MyServiceFault 或其任何超类在此上下文中是已知的。最终抛出SOAPFaultException,如另一个答案中所述。【参考方案2】:
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPFault;
import javax.xml.ws.soap.SOAPFaultException;
import javax.xml.namespace.QName;
...

SOAPFactory soapFactory = SOAPFactory.newInstance();
SOAPFault soapFault = soapFactory.createFault(
        "Your custom message", 
         new QName("http://schemas.xmlsoap.org/soap/envelope/", "Client")); 
throw new SOAPFaultException(soapFault);

要选择正确的故障代码,请参阅http://www.tutorialspoint.com/soap/soap_fault.htm。

【讨论】:

以上是关于如何在 JAX-WS Web 服务上引发自定义错误?的主要内容,如果未能解决你的问题,请参考以下文章

在自定义登录页面上引发错误时下一个身份验证“凭据”重定向

SharePoint 自定义 Web 部件在对象“xxx”、数据库“yyy”、所有者“dbo”上引发 SELECT 权限被拒绝

JAX-WS 客户端:跨多个服务维护会话/cookie

如何从 JAX-WS Web 服务中访问 ServletContext?

由客户端不视为相同类型的 Web 服务引发的自定义异常(使用共享程序集)

如何避免需要在 CXF 或 JAX-WS 生成的 Web 服务客户端中指定 WSDL 位置?