Web service领域的一项重要任务是学习如何处理异常。在JAX-RPC(基于Java API for XML的RPC)兼容的Web service中,异常处理应该不是特别复杂,因为JAX-RPC规范约束着这样的任务。但是,了解编写不同类型客户机(基于存根的或者动态的)的一些编码方面的细微差别非常有益。
虽然目前市场上有许多JAX-RPC规范的实现者,但BEA WebLogic是最早实现JAX-RPC规范的实现者之一。最近,对WebLogic Web Service中的异常处理进行了修改,主要是为了合并对特定于服务的异常处理的支持。让我们看一看BEA WebLogic Server Web service中的异常处理。为了确保能够正确处理异常,我们将介绍与该规范相关的方面、它在WebLogic Server中的实现、编码实践和故障检修技巧等。首先让我们看一看异常处理的一些具体细节。
基础知识
在Web service中,由Web service端点抛出的异常是作为SOAP错误传递给客户机的。根据JAXP-RPC规范,SOAP错误被映射到javax.xml.rpc.soap.SOAPFaultException、特定于服务的异常类,或者java.rmi.RemoteException。
虽然有些异常可以由服务器端抛出:
java.lang.RuntimeException
java.rmi.RemoteException
javax.xml.rpc.soap.SOAPFaultException
(which extends java.lang.RuntimeException)
user-defined exceptions
(mapped to wsdl:fault in the WSDL).
在客户端,可能捕获的异常如下所示(包括SOAPFaultException,但不包括 java.lang.RuntimeException):
java.rmi.RemoteException
javax.xml.rpc.soap.SOAPFaultException
user-defined exceptions.
在Web 服务描述语言(WSDL)中,wsdl:fault元素是wsdl:operation中的一个可选元素,它指定了所有错误消息的抽象消息格式,这些错误消息可以作为远程操作的结果输出。根据WSDL规范,错误消息必须具有单独的一部分。wsdl:fault被映射到java. rmi.RemoteException(或其子类)、特定于服务的Java异常,或者javax.xml.rpc.soap.SOAPFaultException。
清单 1给出了从定义wsdl:fault的WSDL中摘录的一部分。wsdl:operation sendSOAPFault 中定义了一个wsdl:fault MyException,并用单独的一部分定义了wsdl:fault消息的MyException,它被映射为java:examples.webservices.basic.javaclass:MyException类型。
清单 1. 以下是包含一条wsdl:fault消息的WSDL。根据WSDL的规范,错误消息必须具有单独的一部分。
<types xmlns:tns="http://www.bea.com/servers/
wls70/samples/examples/webservices/basic/
javaclass"
xmlns:wsr="http://www.openuri.org/2002/10/
soap/reliability/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/
soap12/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl
/mime/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/
encoding/"
xmlns:soap12enc="http://www.w3.org/2003/05/
soap-encoding"
xmlns:conv="http://www.openuri.org/2002/04/
wsdl/conversation/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<xsd:schema xmlns:xsd="http://www.w3.org/2001/
XMLSchema"
xmlns:stns="java:examples.webservices.basic.
javaclass" elementFormDefault="qualified"
attributeFormDefault="qualified"
targetNamespace="java:examples.webservices.
basic.javaclass">
<xsd:element type="stns:MyException"
name="MyException">
</xsd:element>
<xsd:complexType name="MyException">
<xsd:sequence>
<xsd:element type="xsd:int"
name="errorId"
minOccurs="1" maxOccurs="1">
</xsd:element>
<xsd:element type="xsd:string" name="errorMessage" minOccurs="1"
nillable="true"
maxOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
<message name="MyException">
<part xmlns:partns="java:examples.webservices.
basic.javaclass" type="partns:MyException"
name="MyException">
</part>
</message>
<portType name="HelloWorldPort">
<operation name="sendSOAPFault">
<input message="tns:sendSOAPFault">
</input>
<output message= "tns:sendSOAPFaultResponse">
</output>
<fault name="MyException" message="tns:MyException">
</fault>
</operation>
</portType>
特定于服务的Java异常(由wsdl:fault和相应的wsdl:message映射)直接或间接地扩展了java.lang.Exception类。wsdl:message中单独的消息部分(从wsdl:fault元素中引用)可能是xsd:complexType类型,或者是简单的XML类型。
现在,让我们来讨论对SOAPFaultException和特定于服务的异常的处理。
处理SOAPFaultException
SOAPFaultException表示一个SOAP错误。这种异常是由相应的wsdl:operation映射的Java方法抛出的。
SOAP错误中的消息部分映射到detail元素的内容,通过SOAPFaultException上的getDetail方法可以访问该元素。javax.xml.soap.SOAPFactory 的CreateDetail方法创建了javax.xml.soap.Detail的一个实例。faultstring提供了SOAP错误的易于人们阅读的描述。而faultcode元素则提供SOAP错误的算法映射。
SOAPFaultException类的结构如下所示:
package javax.xml.rpc.soap;
public class SOAPFaultException extends java.lang.RuntimeException {
public SOAPFaultException(QName faultcode,
String faultstring,
String faultactor,
javax.xml.soap.Detail detail) { ... }
public QName getFaultCode() { ... }
public String getFaultString() { ... } public String getFaultActor() { ... }
public javax.xml.soap.Detail getDetail() { ... }
让我们看一看下面两个例子。作为服务实现的一个示例,清单 2给出一个Web service的服务器端实现,在这个实现中,sendSOAPFault()方法抛出一个SOAPFaultException。作为客户端实现的一个示例,清单 3显示了一个调用sendSOAPFault()操作的Web service客户端。这是一个基于存根的客户机,它捕获从sendSOAPFault()操作中抛出的SOAPFaultException。
清单 2. 该Web service的服务器端实现显示了抛出SOAPFaultException的sendSOAPFault()方法。
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.Detail;
import javax.xml.soap.SOAPException;
import javax.xml.namespace.QName;
import javax.xml.rpc.soap.SOAPFaultException;
public final class HelloWorld {
public void sendSOAPFault(){
Detail detail = null;
try{
detail = SOAPFactory.newInstance().createDetail();
detail.addChildElement("MyDetails").addTextNode("failed");
}catch( SOAPException e ){
e.printStackTrace();
}
throw new SOAPFaultException(new QName(
"http://www.bea.com/samples/ws/fault", "ServerFailed"),
"sendSOAPFault method failed", "http://foo/bar/baz/", detail);
}
}
清单 3. 这个基于存根的Web service客户机将处理SOAPFaultException异常。
import javax.xml.rpc.soap.SOAPFaultException;
import java.rmi.RemoteException;
public final class Client {
public Client() {}
public static void main(String[] argv)
throws Exception
{
// Setup the global JAXM message factory
System.setProperty( "javax.xml.soap.MessageFactory",
"weblogic.webservice.core.soap.MessageFactoryImpl");
// Setup the global JAX-RPC service factory
System.setProperty( "javax.xml.rpc.ServiceFactory",
"weblogic.webservice.core.rpc.
ServiceFactoryImpl");
HelloWorld_Impl ws = new HelloWorld_Impl(argv[0]);
HelloWorldPort port = ws.getHelloWorldPort();
try { port.sendSOAPFault();
} // try
catch(SOAPFaultException ex) {System.out.println(ex.toString());
ex.printStackTrace();
}
catch(RemoteException ex) {
if (ex.getCause() instanceof SOAPFaultException) {
SOAPFaultException fault = (SOAPFaultException)ex.getCause();
System.out.println("[Client] Fault Detail : " +
fault.getDetail().toString());
System.out.println("[Client] Fault Actor : " + fault.getFaultActor());
System.out.println("[Client] Fault String : " + fault.getFaultString());
}
System.out.println("[Client]
Exception stack trace :");
ex.printStackTrace();
}
}
}
在WebLogic Server Web service客户机存根中,由于错误(由服务器抛出的SOAPFaultException异常所引起的)被映射到java.rmi.RemoteException,所以Client.java(一种基于存根的客户端)可能需要捕获java.rmi.RemoteException。然而,如果使用采用javax.xml.rpc.Call接口的动态调用接口(DLL)客户机,您可能需要捕获SOAPFaultException。关于在调用sendSOAPFault()时,SOAP请求/响应消息的示例,请在线查看清单 4。
清单 4. 调用sendSOAPFault()的SOAP 请求/响应消息。
[java] <!-------------------- REQUEST ---------------->
[java] URL: http://localhost:7001/basic_javaclass/HelloWorld
[java] Headers:
[java] SOAPAction: [""]
[java] Content-Type: [text/xml]
[java] <env:Envelope xmlns:env= "http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc=
"http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/
XMLSchema"><env:Header/>
<env:Body env:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/">
<m:sendSOAPFault xmlns:m="http://www.bea.com/servers/wls70/
samples/examples/webservices/basic/javaclass"/>
</env:Body>
</env:Envelope>
[java] <!-------------------- END REQUEST ------------>
[java] <!-------------------- RESPONSE --------------->
[java] URL: http://localhost:7001/basic_javaclass/
HelloWorld
[java] Response Code :500
[java] Headers :
[java] Date=Fri, 18 Jun 2004 17:20:15 GMT
[java] Server=WebLogic Server 8.1 SP2 Fri Dec 5
15:01:51 PST 2003 316284
with CR182483
[java] Content-Length=587
[java] Content-Type=text/xml; charset=utf-8
[java] Envelope:
[java] <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/
envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc=
"http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<env:Header/>
<env:Body><env: Fault xmlns:fault="http://www.bea.com/samples/ws/fault">
<faultcode>
fault:ServerFailed
</faultcode>
<faultstring>
sendSOAPFault method failed</faultstring>
<faultactor>
http://foo/bar/baz/
</faultactor>
<detail><MyDetails>failed</MyDetails></detail>
</env:Fault>
</env:Body>
</env:Envelope>
[java] <!-------------------- END RESPONSE ----------->
[java] [Client] Fault Detail : <detail>
[java] <MyDetails>failed</MyDetails>
[java] java.rmi.RemoteException: SOAP
Fault:javax.xml.rpc.soap.SOAPFaultException:
sendSOAPFault method failed
[java] Detail:
[java] <detail>
[java] </detail>
[java] [Client] Fault Actor : http://foo/bar/baz/
[java] [Client] Fault String : sendSOAPFault method failed
[java] <MyDetails>failed</MyDetails>
[java] </detail>; nested exception is:
[java] javax.xml.rpc.soap.SOAPFaultException: sendSOAPFault method failed
[java] [Client] Exception stack trace :
[java] at examples.webservices.basic.javaclass.
HelloWorldPort_Stub.send
SOAPFault(HelloWorldPort_Stub.java:29)
[java] at examples.webservices.basic.javaclass.
Client.main(Client.java:37)
[java] Caused by:
javax.xml.rpc.soap.SOAPFaultException:
sendSOAPFault method failed
[java] at weblogic.webservice.core.ClientDispatcher.receive(ClientDispatcher.java:313)
[java] at weblogic.webservice.core.ClientDispatcher.dispatch(ClientDispatcher.java:144)
[java] at weblogic.webservice.core.DefaultOperation.invoke(DefaultOperation.java:457)
[java] at weblogic.webservice.core.DefaultOperation.nvoke(DefaultOperation.java:443)
[java] at weblogic.webservice.core.rpc.tubImpl._invoke(StubImpl.java:290)
[java] at examples.webservices.basic.
avaclass.HelloWorldPort_Stub.send
OAPFault(HelloWorldPort_Stub.java:25)
[java] ... 1 more
处理特定于服务的异常
特定于服务的Java异常(由wsdl:fault和相应的wsdl:message映射)直接或者间接地扩展了java.lang.Exception类。wsdl:message中单独的消息部分(从wsdl:fault元素中引用)可能是xsd:complexType类型,也可能是简单的XML类型。
清单 5给出一个从wsdl:fault到特定于服务的Java异常的映射。wsdl:message中包含类型MyException的单独一部分,它就是complexType。
清单 5. 包含complexType 类型的wsdl:fault 错误的WSDL。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:stns="java:examples.webservices.basic.
javaclass" elementFormDefault="qualified"
attributeFormDefault="qualified"
targetNamespace="java:examples.webservices.basic.javaclass">
<xsd:element type="stns:MyException" name="MyException">
</xsd:element>
<xsd:complexType name="MyException">
<xsd:sequence>
<xsd:element type="xsd:int" name="errorId" minOccurs="1" maxOccurs="1">
</xsd:element>
<xsd:element type="xsd:string" name="errorMessage" minOccurs="1"
nillable="true" maxOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
<message name="MyException">
<part xmlns:partns="java:examples. webservices.basic.javaclass"
type="partns:MyException" name="MyException">
</part>
</message>
<portType name="HelloWorldPort">
<operation name="sendSOAPFault">
<input message="tns:sendSOAPFault">
</input>
<output message="tns:sendSOAPFaultResponse">
</output>
<fault name="MyException" message="tns:MyException">
</fault>
</operation>
</portType>
注意,在WLS 7.0.x 和 WLS 8.1中,不支持对特定于服务的异常的处理。因此,在WLS 7.0.x 和 WLS 8.1中,是从定义complexType类型的wsdl:fault错误的WSDL中生成Web service,这将导致以下结果:
生成的服务中的方法没有抛出有关的异常。
一旦从服务器端抛出异常,在线的SOAP消息就会认为这一异常是基本类型的,而不是MyException类型的。
通过clientgen生成客户端存根/代理将无法生成异常的特有实现。
相反,当在抛出用户定义的或特定于服务的异常的Java应用程序中生成Web service时,会遇到类似的问题。
在WLS 8.1 SP1和更高的版本中,通过实现JAX-RPC规范的5.5.5 和 4.3.6小节,可以添加这种支持。而在WLS 7.0.x和 WLS 8.1中,作为权宜之计,需要在服务器端抛出SOAPFaultException,而不是抛出特定于服务的异常。
为了捕获异常的正确语义,将经过检查的、用户定义的异常定义为服务端点接口(SEI)的一部分是一种很好的编程/设计习惯。在该模型中,Web service是从某个源(比如Java 类或企业JavaBean[EJB])中生成的,用户定义的异常将被映射到WSDL的wsdl:operation内部的wsdl:fault。相反,在该模型中,Web service是在WSDL中生成的,应该根据期望抛出的异常的类型定义合适的wsdl:faults。
清单 6是举例说明了处理特定于服务的异常的方法的一个示例。该清单有Web service的服务器端实现,该实现抛出了MyException,这是一个特定于服务的异常。
清单 6. 以下是处理特定于服务的异常的一个例子,首先显示的是MyException实现,然后显示的是Web service后端组件。
public class MyException extends Exception {
private String errorMessage;
private int errorId;
//public MyException();
public MyException(String errorMessage,
int errorId) {
this.errorMessage = errorMessage;
this.errorId = errorId;
}
public void setErrorMessage(String errorMessage)
{ this.errorMessage = errorMessage; }
public String getErrorMessage()
{ return errorMessage; }
public void setErrorId(int errorId)
{ this.errorId = errorId; }
public int getErrorId() { return errorId; }
}
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.Detail;
import javax.xml.soap.SOAPException;
import javax.xml.namespace.QName;
import javax.xml.rpc.soap.SOAPFaultException;
public final class HelloWorld {
public void sendSOAPFault()throws MyException
{
throw new MyException("sendSOAPFault() call fails !", 10);
}
}
清单 7和清单 8都包含调用sendSOAPFault()操作的Web客户端的实现。清单 7为基于存根的客户机提供了实现,而清单 8为动态调用接口(DLL)或动态Web service客户机提供了实现。后者捕获由sendSOAPFault()操作抛出的SOAPFaultException异常。
清单 7. 处理特定于服务的异常MyException的基于存根的客户机的一个示例。
import javax.xml.rpc.soap.SOAPFaultException;
import java.rmi.RemoteException;
public final class Client {
public Client() {}
public static void main(String[] argv)
throws Exception
{
// Setup the global JAXM message factory System.setProperty(
"javax.xml.soap.MessageFactory", "weblogic.webservice.core.soap.
MessageFactoryImpl");
// Setup the global JAX-RPC service factory System.setProperty(
"javax.xml.rpc.ServiceFactory", "weblogic.webservice.core.rpc.
ServiceFactoryImpl");
HelloWorld_Impl ws = new HelloWorld_Impl(argv[0]);
HelloWorldPort port = ws.getHelloWorldPort();
try {
port.sendSOAPFault();
} // try
catch(MyException ex) {
System.out.println("[Client]
Exception caught is : " + ex.toString());
System.out.println("[Client] errorMessage : " + ex.getErrorMessage());
System.out.println("[Client] errorId : " + ex.getErrorId());
System.out.println("[Client]
Exception stack trace :");
ex.printStackTrace();
}
}
}
清单 8. 在这里,您将看到处理特定于服务的异常MyException的DII客户机或动态客户机。
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.Service;
import javax.xml.rpc.Call;
import javax.xml.rpc.ParameterMode;
import javax.xml.namespace.QName;
import javax.xml.rpc.soap.SOAPFaultException;
import java.rmi.RemoteException;
public class DynamicClient {
public static void main(String[] args)
throws Exception {
//set weblogic ServiceFactory System.setProperty(
"javax.xml.rpc.ServiceFactory", "weblogic.webservice.core.rpc.
ServiceFactoryImpl" );
//create service factory
ServiceFactory factory = ServiceFactory.newInstance();
String targetNamespace = "http://www.bea.com/servers/wls70/
samples/examples/webservices/basic/javaclass";
QName serviceName = new QName(targetNamespace, "HelloWorld");
QName portName = new QName(targetNamespace, "HelloWorldPort");
QName operationName = new QName(targetNamespace, "sendSOAPFault");
Service service = factory.createService( serviceName);
Call call = service.createCall();
call.setPortTypeName(portName);
call.setOperationName(operationName);
call.setTargetEndpointAddress("http://localhost:7001/basic_javaclass/
HelloWorld?WSDL");
try {
call.invoke(new Object[]{});
} // try
catch(SOAPFaultException ex) {
System.out.println("[Client] Fault Detail : " + ex.getDetail().toString());
System.out.println("[Client] Fault Actor : " + ex.getFaultActor());
System.out.println("[Client] Fault String : " + ex.getFaultString());
ex.printStackTrace();
}
catch(RemoteException ex) {
if (ex.getCause() instanceof
SOAPFaultException) {
SOAPFaultException fault = (SOAPFaultException)ex.getCause();
System.out.println("[Client] Fault Detail : " + fault.getDetail().toString());
System.out.println("[Client] Fault Actor : " + fault.getFaultActor());
System.out.println("[Client] Fault String : " + fault.getFaultString());
}
System.out.println("[Client] Exception stack trace :");
ex.printStackTrace();
}
}
}
在WebLogic Server Web客户端存根中,由于错误(由服务器抛出特定于服务的异常所引起的)被映射到特定于服务的异常,所以Client.java(一种基于存根的客户端)可能需要捕获特定于服务的异常。但使用javax.xml.rpc.Call 接口的DLL客户端可能需要捕获RemoteException 或 SOAPFaultException。特定于服务的异常可能被封装在SOAPFaultException中。
关于在从基于存根的客户机中调用sendSOAPFault()时,SOAP请求/响应消息的一个示例,请在线查看清单 9,而从动态客户端调用sendSOAPFault()时的示例,请在线查看清单 10。
清单 9. SOAP对从基于存根的客户机中调用sendSOAPFault()进行追踪。
[java] <!-------------------- REQUEST ---------------->
[java] URL: http://localhost:7001/basic_javaclass/HelloWorld
[java] Headers:
[java] SOAPAction: [""]
[java] Content-Type: [text/xml]
[java] <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<env:Header/>
<env:Body env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<m:sendSOAPFault xmlns:m="http://www.bea.com/servers/wls70/samples/
examples/webservices/basic/javaclass"/>
</env:Body>
</env:Envelope>
[java] <!-------------------- END REQUEST ------------>
[java] <!-------------------- RESPONSE --------------->
[java] URL: http://localhost:7001/basic_javaclass/HelloWorld
[java] Response Code :500
[java] Headers:
[java] Date=Wed, 23 Jun 2004 21:39:06 GMT
[java] Server=WebLogic Server 8.1 SP2 Fri Dec 5
15:01:51 PST 2003 316284
with CR182483
[java] Content-Length=730
[java] Content-Type=text/xml; charset=utf-8
[java] Envelope :
[java] <?xml version="1.0" encoding="utf-8" standalone="yes"?><env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<env:Header/>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>Service specific exception:
examples.webservices.basic.javaclass.MyException
</faultstring>
<detail>
<MyException xmlns:n1="java:examples.webservices.basic.javaclass"
xsi:type="n1:MyException">
<errorId xsi:type="xsd:int">10</errorId>
<errorMessage xsi:type="xsd:string">
sendSOAPFault() call fails !
</errorMessage>
</MyException>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
[java] <!-------------------- END RESPONSE ----------->
[java] [Client] Exception caught is : MyException{
errorId=<10> errorMessage=<sendSOAPFault()
call fails !> }
[java] [Client] errorMessage : sendSOAPFault()
call fails !
[java] [Client] errorId : 10
[java] [Client] Exception stack trace :
[java] MyException{ errorId=<10>
errorMessage=<sendSOAPFault() call fails !> }
[java] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[java] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.
java:39)
[java] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(
DelegatingConstructorAccessorImpl.java:27)
[java] at java.lang.reflect.Constructor.newInstance(
Constructor.java:274)
[java] at weblogic.xml.schema.binding.BeanExceptionCodecBase.invokeConstructor(
BeanExceptionCodecBase.java:134)
[java] at weblogic.xml.schema.binding.BeanExceptionCodecBase.deserialize(
BeanExceptionCodecBase.java:72)
[java] at weblogic.xml.schema.binding.RuntimeUtils.invoke_deserializer(RuntimeUtils.java:428)
[java] at weblogic.xml.schema.binding.RuntimeUtils.invoke_deserializer(RuntimeUtils.java:328)
[java] at weblogic.webservice.core.DefaultPart.toJava(DefaultPart.java:384)
[java] at weblogic.webservice.core.FaultMessage.toJava(FaultMessage.java:227)
[java] at weblogic.webservice.core.ClientDispatcher.deserializeFault(ClientDispatcher.java:391)
[java] at weblogic.webservice.core.ClientDispatcher.receive(ClientDispatcher.java:317)
[java] at weblogic.webservice.core.ClientDispatcher.dispatch(ClientDispatcher.java:144)
[java] at weblogic.webservice.core.DefaultOperation.invoke(DefaultOperation.java:457)
[java] at weblogic.webservice.core.DefaultOperation.invoke(DefaultOperation.java:443)
[java] at weblogic.webservice.core.rpc.StubImpl._invoke(StubImpl.java:290)
[java] at examples.webservices.basic.javaclass.HelloWorldPort_Stub.send
SOAPFault(HelloWorldPort_Stub.java:25)
[java] at examples.webservices.basic.javaclass.Client.main(Client.java:35)
[java] Caused by: javax.xml.rpc.soap.SOAPFaultException: Service specific exception:
examples.webservices.basic.javaclass.MyException
[java] at weblogic.webservice.core.ClientDispatcher.receive(ClientDispatcher.java:313)
[java] ... 6 more
清单 10. SOAP对从动态客户机中调用sendSOAPFault()进行追踪。
[java] <!-------------------- REQUEST ---------------->
[java] URL : http://localhost:7001/basic_javaclass/ HelloWorld?WSDL
[java] Headers :
[java] SOAPAction: [""]
[java] Content-Type: [text/xml]
[java] <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc=
"http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/
XMLSchema">
<env:Header/>
<env:Body env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<m:sendSOAPFault xmlns:m="http://www.bea.com/servers/wls70/samples/
examples/webservices/basic/javaclass"/>
</env:Body>
</env:Envelope>
[java] <!-------------------- END REQUEST ------------>
[java] <!-------------------- RESPONSE --------------->
[java] URL : http://localhost:7001/basic_javaclass/
HelloWorld?WSDL
[java] Response Code :500
[java] Headers:
[java] Date=Wed, 23 Jun 2004 21:23:15 GMT
[java] Server=WebLogic Server 8.1 SP2 Fri Dec 5
15:01:51 PST 2003 316284
with CR182483
[java] Content-Length=730
[java] Content-Type=text/xml; charset=utf-8
[java] Envelope:
[java] <?xml version="1.0" encoding="utf-8" standalone="yes"?><env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/
2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<env:Header/>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>Service specific exception:examples.webservices.basic.javaclass.MyException
</faultstring>
<detail>
<MyException xmlns:n1="java:examples.webservices.basic.javaclass"
xsi:type="n1:MyException">
<errorId xsi:type="xsd:int">10</errorId>
<errorMessage xsi:type="xsd:string">
sendSOAPFault() call fails !
</errorMessage>
</MyException>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
[java] <!-------------------- END RESPONSE ----------->
[java] [Client] Fault Detail : <detail>
[java] <MyException xmlns:n1="java:examples.webservices.basic.javaclass"
[java] xsi:type="n1:MyException">
[java] <errorId xsi:type="xsd:int">10</errorId>
[java] javax.xml.rpc.soap.SOAPFaultException:
Service specific exception:
examples.webservices.basic.javaclass.MyException
[java] at weblogic.webservice.core.ClientDispatcher.receive(ClientDispatcher.java:313)
[java] <errorMessage xsi:type="xsd:string">
sendSOAPFault() call fails!
</errorMessage>
[java] at weblogic.webservice.core.ClientDispatcher.dispatch(ClientDispatcher.java:144)
[java] at weblogic.webservice.core.DefaultOperation.invoke(DefaultOperation.java:457)
[java] </MyException>
[java] </detail>
[java] [Client] Fault Actor : null
[java] [Client] Fault String : Service specific
exception: examples.webservices.basic.
javaclass.MyException
[java] at weblogic.webservice.core.DefaultOperation.invoke(DefaultOperation.java:443)
[java] at weblogic.webservice.core.rpc.CallImpl.invoke(CallImpl.java:558)
[java] at weblogic.webservice.core.rpc.CallImpl.invoke(CallImpl.java:411)
[java] at examples.webservices.basic.javaclass.DynamicClient.main(DynamicClient.java:39)
实现特定于服务的异常的使用是一个很好的编码习惯。如果遇到问题,请参阅侧栏“异常处理的故障检修技巧”。不久,您就会像一位真正的专家那样处理异常。
|