接口类:IMyService.java
@WebResult(name="testExceptionResult") public void testException() throws MyException;
实现类:MyServiceImpl.java
@Override public void testException() throws MyException{ throw new MyException("this is my exception"); }
异常类:MyException.java
public class MyException extends Exception{ public MyException() { super(); // TODO Auto-generated constructor stub } public MyException(String message, Throwable cause) { super(message, cause); // TODO Auto-generated constructor stub } public MyException(String message) { super(message); // TODO Auto-generated constructor stub } public MyException(Throwable cause) { super(cause); // TODO Auto-generated constructor stub } }
生成的wsdl文件:
<?xml version="1.0" encoding="UTF-8" ?> - <!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --> - <!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --> - <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://ws01.yzl.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws01.yzl.com/" name="MyServiceImplService"> - <types> - <xsd:schema> <xsd:import namespace="http://ws01.yzl.com/" schemaLocation="http://localhost:8888/ws01?xsd=1" /> </xsd:schema> </types> - <message name="testException"> <part name="parameters" element="tns:testException" /> </message> - <message name="testExceptionResponse"> <part name="parameters" element="tns:testExceptionResponse" /> </message> - <message name="MyException"> <part name="fault" element="tns:MyException" /> </message> - <portType name="IMyService"> - <operation name="testException"> <input message="tns:testException" /> <output message="tns:testExceptionResponse" /> <fault message="tns:MyException" name="MyException" /> </operation> </portType> - <binding name="MyServiceImplPortBinding" type="tns:IMyService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> - <operation name="testException"> <soap:operation soapAction="" /> - <input> <soap:body use="literal" /> </input> - <output> <soap:body use="literal" /> </output> - <fault name="MyException"> <soap:fault name="MyException" use="literal" /> </fault> </operation> </binding> - <service name="MyServiceImplService"> - <port name="MyServiceImplPort" binding="tns:MyServiceImplPortBinding"> <soap:address location="http://localhost:8888/ws01" /> </port> </service> </definitions>
生成的xsd文件:
<?xml version="1.0" encoding="UTF-8" ?> - <!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --> - <xs:schema xmlns:tns="http://ws01.yzl.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://ws01.yzl.com/"> <xs:element name="MyException" type="tns:MyException" /> <xs:element name="testException" type="tns:testException" /> <xs:element name="testExceptionResponse" type="tns:testExceptionResponse" /> - <xs:complexType name="testException"> <xs:sequence /> </xs:complexType> - <xs:complexType name="testExceptionResponse"> <xs:sequence /> </xs:complexType> - <xs:complexType name="MyException"> - <xs:sequence> <xs:element name="message" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:schema>
使用myeclipse的Web Service Explorer调用该接口方法后返回的SOAP消息
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <S:Fault xmlns:ns3="http://www.w3.org/2003/05/soap-envelope"> <faultcode>S:Server</faultcode> <faultstring>this is my exception</faultstring> <detail> <ns2:MyException xmlns:ns2="http://ws01.yzl.com/"> <message>this is my exception</message> </ns2:MyException> <ns2:exception xmlns:ns2="http://jax-ws.dev.java.net/" class="com.yzl.ws01.MyException" note="To disable this feature, set com.sun.xml.internal.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace system property to false"> <message>this is my exception</message> <ns2:stackTrace> <ns2:frame class="com.yzl.ws01.MyServiceImpl" file="MyServiceImpl.java" line="56" method="testException" /> <ns2:frame class="sun.reflect.NativeMethodAccessorImpl" file="NativeMethodAccessorImpl.java" line="native" method="invoke0" /> <ns2:frame class="sun.reflect.NativeMethodAccessorImpl" file="NativeMethodAccessorImpl.java" line="39" method="invoke" /> <ns2:frame class="sun.reflect.DelegatingMethodAccessorImpl" file="DelegatingMethodAccessorImpl.java" line="25" method="invoke" /> <ns2:frame class="java.lang.reflect.Method" file="Method.java" line="597" method="invoke" /> <ns2:frame class="com.sun.xml.internal.ws.api.server.InstanceResolver$1" file="InstanceResolver.java" line="235" method="invoke" /> <ns2:frame class="com.sun.xml.internal.ws.server.InvokerTube$2" file="InvokerTube.java" line="135" method="invoke" /> <ns2:frame class="com.sun.xml.internal.ws.server.sei.EndpointMethodHandler" file="EndpointMethodHandler.java" line="246" method="invoke" /> <ns2:frame class="com.sun.xml.internal.ws.server.sei.SEIInvokerTube" file="SEIInvokerTube.java" line="82" method="processRequest" /> <ns2:frame class="com.sun.xml.internal.ws.api.pipe.Fiber" file="Fiber.java" line="587" method="__doRun" /> <ns2:frame class="com.sun.xml.internal.ws.api.pipe.Fiber" file="Fiber.java" line="546" method="_doRun" /> <ns2:frame class="com.sun.xml.internal.ws.api.pipe.Fiber" file="Fiber.java" line="531" method="doRun" /> <ns2:frame class="com.sun.xml.internal.ws.api.pipe.Fiber" file="Fiber.java" line="428" method="runSync" /> <ns2:frame class="com.sun.xml.internal.ws.server.WSEndpointImpl$2" file="WSEndpointImpl.java" line="232" method="process" /> <ns2:frame class="com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit" file="HttpAdapter.java" line="460" method="handle" /> <ns2:frame class="com.sun.xml.internal.ws.transport.http.HttpAdapter" file="HttpAdapter.java" line="233" method="handle" /> <ns2:frame class="com.sun.xml.internal.ws.transport.http.server.WSHttpHandler" file="WSHttpHandler.java" line="95" method="handleExchange" /> <ns2:frame class="com.sun.xml.internal.ws.transport.http.server.WSHttpHandler" file="WSHttpHandler.java" line="80" method="handle" /> <ns2:frame class="com.sun.net.httpserver.Filter$Chain" file="Filter.java" line="65" method="doFilter" /> <ns2:frame class="sun.net.httpserver.AuthFilter" file="AuthFilter.java" line="65" method="doFilter" /> <ns2:frame class="com.sun.net.httpserver.Filter$Chain" file="Filter.java" line="68" method="doFilter" /> <ns2:frame class="sun.net.httpserver.ServerImpl$Exchange$LinkHandler" file="ServerImpl.java" line="555" method="handle" /> <ns2:frame class="com.sun.net.httpserver.Filter$Chain" file="Filter.java" line="65" method="doFilter" /> <ns2:frame class="sun.net.httpserver.ServerImpl$Exchange" file="ServerImpl.java" line="527" method="run" /> <ns2:frame class="java.util.concurrent.ThreadPoolExecutor$Worker" file="ThreadPoolExecutor.java" line="886" method="runTask" /> <ns2:frame class="java.util.concurrent.ThreadPoolExecutor$Worker" file="ThreadPoolExecutor.java" line="908" method="run" /> <ns2:frame class="java.lang.Thread" file="Thread.java" line="662" method="run" /> </ns2:stackTrace> </ns2:exception> </detail> </S:Fault> </S:Body> </S:Envelope>
测试类:
@Test public void test1() throws Exception{ String namespace = "http://ws01.yzl.com/"; String wsdlUrl = "http://localhost:8080/ws?wsdl"; //1、创建服务(Service) URL url = new URL(wsdlUrl); QName qname = new QName(namespace,"MyServiceImplService"); Service service = Service.create(url, qname); //2、创建Dispatch //public interface Dispatch<T>extends BindingProviderDispatch 接口提供对动态调用服务端点操作的支持。javax.xml.ws.Service 接口作为创建 Dispatch 实例的工厂。 Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(namespace,"MyServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE); //3、创建SOAPMessage MessageFactory factory = MessageFactory.newInstance(); SOAPMessage message = factory.createMessage(); SOAPPart part = message.getSOAPPart(); SOAPEnvelope envelope = part.getEnvelope(); SOAPBody body = envelope.getBody(); QName portQname = new QName(namespace, "testException","ns"); body.addBodyElement(portQname); //4、通过Dispatch传递消息,并返回响应消息 SOAPMessage returnMessage = dispatch.invoke(message); returnMessage.writeTo(System.out);//打印返回消息 System.out.println(); }
结果:
javax.xml.ws.soap.SOAPFaultException: test exception at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:178) at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:111) at com.sun.xml.internal.ws.client.dispatch.DispatchImpl.doInvoke(DispatchImpl.java:176) at com.sun.xml.internal.ws.client.dispatch.DispatchImpl.invoke(DispatchImpl.java:195) at com.ws02.TestWsException.test1(TestWsException.java:42) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41) at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.junit.runners.ParentRunner.run(ParentRunner.java:220) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: com.ws01.MyException: test exception at com.ws01.IServiceImp.testException(IServiceImp.java:10) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.xml.internal.ws.api.server.InstanceResolver$1.invoke(InstanceResolver.java:235) at com.sun.xml.internal.ws.server.InvokerTube$2.invoke(InvokerTube.java:135) at com.sun.xml.internal.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:246) at com.sun.xml.internal.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:82) at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:587) at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:546) at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:531) at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:428) at com.sun.xml.internal.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:232) at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:460) at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:233) at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(WSHttpHandler.java:95) at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:80) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65) at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:65) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:68) at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:555) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65) at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:527) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619)
客户端抛出了SOAPFaultException异常,服务端没抛出异常
如果修改服务端的代码
throw new MyException("test exception"); 修改为: throw new RuntimeException("service runtime Exception");
那么客户端和服务端都将抛出异常,因为服务端并未将runtimeException异常抛给客户端。
抛出的异常客户端可以通过捕获SOAPFaultException来获取服务端的错误