我们先上一个示例,先定义服务端代码:
HelloWordOne.java:
package ch05.ts;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface HelloWordOne {
@WebMethod
void sayHello(String name,String hw) throws HelloException;
}
HelloWordOneImpl.java:
package ch05.ts;
import javax.jws.WebService;
@WebService(endpointInterface = "ch05.ts.HelloWordOne")
public class HelloWordOneImpl implements HelloWordOne {
@Override
public void sayHello(String name, String hw) throws HelloException {
if(null != name && !"".equals(name)){
System.out.println(name + ":" + hw);
}else{
throw new HelloException("name is null","名称不能为空");
}
}
}
HelloException.java,这个是自定义的异常类:
package ch05.ts;
public class HelloException extends Exception {
private String details;
public HelloException(String reason,String details){
super(reason);
this.details = details;
}
public String getFaultInfo(){
return details;
}
}
HelloWordOnePublisher.java,服务发布类:
package ch05.ts;
import javax.xml.ws.Endpoint;
public class HelloWordOnePublisher {
public static void main(String[] args) {
Endpoint.publish("http://localhost:8765/ts", new HelloWordOneImpl());
}
}
根据发布的服务生成的WSDL文档,创建客户端代码:
HelloWordOne.java,HelloWordOneImplService.java,ObjectFactory.java,package-info.java,SayHello.java,SayHelloResponse.java 这些类源文件我们就不列出来了,因为我们都见过,与以前的例子差不太多。这里我们主要列下面三个。
HelloException.java:
package ch05.client;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for HelloException complex type.
* <p>The following schema fragment specifies the expected content
* contained within this class.
* <pre>
* <complexType name="HelloException">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="faultInfo" type="{http://www.w3.org/2001/XMLSchema}string"
* minOccurs="0"/>
* <element name="message" type="{http://www.w3.org/2001/XMLSchema}string"
* minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "HelloException", propOrder = {
"faultInfo",
"message"
})
public class HelloException {
protected String faultInfo;
protected String message;
/**
* Gets the value of the faultInfo property.
* @return
* possible object is
* {@link String }
*/
public String getFaultInfo() {
return faultInfo;
}
/**
* Sets the value of the faultInfo property.
* @param value
* allowed object is
* {@link String }
*/
public void setFaultInfo(String value) {
this.faultInfo = value;
}
/**
* Gets the value of the message property.
* @return
* possible object is
* {@link String }
*/
public String getMessage() {
return message;
}
/**
* Sets the value of the message property.
* @param value
* allowed object is
* {@link String }
*/
public void setMessage(String value) {
this.message = value;
}
}
HelloException_Exception.java:
package ch05.client;
import javax.xml.ws.WebFault;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.4-b01
* Generated source version: 2.2
*/
@WebFault(name = "HelloException", targetNamespace = "http://ts.ch05/")
public class HelloException_Exception extends Exception {
/**
* Java type that goes as soapenv:Fault detail element.
*/
private HelloException faultInfo;
/**
* @param message
* @param faultInfo
*/
public HelloException_Exception(String message, HelloException faultInfo) {
super(message);
this.faultInfo = faultInfo;
}
/**
* @param message
* @param faultInfo
* @param cause
*/
public HelloException_Exception(String message, HelloException faultInfo,
Throwable cause) {
super(message, cause);
this.faultInfo = faultInfo;
}
/**
* @return
* returns fault bean: ch05.client.HelloException
*/
public HelloException getFaultInfo() {
return faultInfo;
}
}
HelloWordOneClient.java,客户端调用服务:
package ch05.client;
public class HelloWordOneClient {
public static void main(String[] args) {
HelloWordOneImplService service = new HelloWordOneImplService();
HelloWordOne port = service.getHelloWordOneImplPort();
try {
port.sayHello("", "good morning");
} catch (HelloException_Exception e) {
//这里打印:name is null
e.printStackTrace();
//这里打印:名称不能为空
System.out.println(e.getFaultInfo().getFaultInfo());
}
}
}
这里故意抛出一个HelloException异常!执行结果为:
这个示例中,我们定义了一个自定义异常类:HelloException,作为服务声明的异常。发布服务后,随之产生的WSDL文档与普通的WSDL有些不同。WSDL中包括一个消息定义以实现异常。同时在portType部分,除常见的输入和输出消息外,还包括了一个错误消息。下面是相关的WSDL片段:
<message name="sayHello">
<part name="parameters" element="tns:sayHello"/>
</message>
<message name="sayHelloResponse">
<part name="parameters" element="tns:sayHelloResponse"/>
</message>
<message name="HelloException">
<part name="fault" element="tns:HelloException"/>
</message>
<portType name="HelloWordOne">
<operation name="sayHello">
<input wsam:Action="http://ts.ch05/HelloWordOne/sayHelloRequest"
message="tns:sayHello"/>
<output wsam:Action="http://ts.ch05/HelloWordOne/sayHelloResponse"
message="tns:sayHelloResponse"/>
<fault message="tns:HelloException" name="HelloException"
wsam:Action="http://ts.ch05/HelloWordOne/sayHello/Fault/HelloException"/>
</operation>
</portType>
注意:java中实现SOAP报错的异常类必须包括一个拥有两个输入参数的构造方法,其中第一个参数用来传入产生错误的具体原因,第二个参数用来提供相关错误的额外信息。同时在异常类中还必须定义一个getFaultInfo方法,返回错误的详细信息。