SOAP 服务
本节讲述如何编写SOAP服务以及如何在SOAP消息中处理异常和错误。本节讲述以下主题:
创建SOAP服务
SOAP服务是SOAP消息的最终接收者,并且被实现为servlet。要么创建你自己的servlet,要么扩展javax.xml.messaging包中的JAXMServlet类。本节讲述了基于JAXMServlet类创建SOAP服务的过程。
为了创建SOAP服务,你的servlet必须实现ReqRespListener或者OneWayListener接口。ReqRespListener需要返回一个回应。
public class MyServlet extends JAXMServlet implements ReqRespListener{
...
...
}
public SOAPMessage onMessage(SOAP Message msg)
使用任意借口,实现一个叫做onMessage(SOAPMsg)的方法。
以下代码是使用JAXMServlet 的SOAP消费者的完整清单:
public class MyServlet extends JAXMServlet implements ReqRespListener {
public SOAPMessage onMessage(SOAP Message msg) {
//Process message here
}
}
JAXMServlet在使用HTTP POST方法接受消息之后会调用onMessage。你就省去了实现自己的doPost()方法把收到的消息转换成为SOAP消息的麻烦。
OnMessage方法需要分解由servlet传入的SOAP消息并处理它的内容。处理消息包括访问SOAP消息的组成部分。如果在处理消息过程中出现故障,服务需要创建SOAP fault对象并把它发回到客户端。关于处理错误的更多信息,请参见"错误处理"。
以下代码演示了SOAP消息的处理:
{http://xml.coverpages.org/dom.html
SOAPEnvelope env = reply.getSOAPPart().getEnvelope();
SOAPBody sb = env.getBody();
// create Name object for XElement that we are searching for Name ElName = env.createName("XElement");
//Get child elements with the name XElement
Iterator it = sb.getChildElements( ElName );
//Get the first matched child element.
//We know there is only one.
SOAPBodyElement sbe = (SOAPBodyElement) it.next();
//Get the value for XElement
MyValue = sbe.getValue(); }
异常和错误处理
On the client's side, JAXM and SAAJ uses a SOAP exception to handle errors that occur during the generation of the SOAP request or unmarshalling of the response. This section describes the following topics:
在客户端,JAXM和SAAJ使用SOAP异常来处理SOAP 请求生成过程中,或者响应反编组过程中发生的错误。本节讲述以下主题:
错误处理
服务器端代码必须使用SOAPFault对象处理在反编组请求、处理消息、或是编组响应过程中发生的错误。SOAPFault接口扩展了SOAPBodyElement接口。
在服务器端,SOAP消息拥有用来形成错误报告的特定元素和格式:SOAP消息的body可以包含一个SOAPFault元素来报告发生在请求处理过程中的错误。在服务器端创建并且从服务器发回到客户端的SOAP消息包含了SOAPFault对象,它报告了消息生成者没有预期到的任何行为。
SOAPFault元素定义了以下四个子元素
faultcode
标识错误的代码。软件使用该代码为鉴别错误提供一个算法机制。此元素是必需的。
faultstring
一个描述错误代码所标识的错误的字符串。该元素提供了为人们无法理解的错误提供了一个解释。此元素是必需的。
faultactor
指定错误来源的URI:谁引起了错误。如果消息没有通过任何中间站直接发送给它的最终目的地,该元素不是必需的。如果在中间站发生了错误,这个错误必须包含一个faultactor元素。
detail
该元素持有与body元素相关的特定信息。如果body元素的内容不能够被成功处理,它就必须被给出。因此,如果这个元素丢失了,客户端应该推断出body元素已经被处理了。除了畸形负载,这个元素对任何错误都不是必须的,你可以在其他情况下用它来为客户端提供附加信息。
预定义的错误代码
SOAP规范列出了以下四个预定义的faultcode值:
VersionMismatch
处理方发现SOAP envelope元素有一个不合法的命名空间;也就是说,SOAPEnvelope元素的命名空间不是http://schemas.xmlsoap.org/soap/envelope/.
MustUnderstand
SOAPHeader元素的一个直接子元素要么无法理解,要么接收者不能正确处理。这个元素的MustUnderstand属性设被为1(true)。
Client
消息格式不正确或者没包含合适的信息。例如,消息没有包含正确的认证或付款信息。客户端应该翻译这个代码从而指定这个消息在重新发送之间必须被修改。如果这是一个返回代码,SOAPFault对象应该包括一个detailEntry对象,它为格式错误的消息提供附加信息。
Server
该消息由于一些与它的内容没有联系的原因而不能被处理。例如,消息的一个处理者无法与另一个上游的、没有相应的消息处理者进行通信。或者,服务器需要访问的数据库崩溃了。客户端应该解释这个错误,以指出事务可以在以后的某个及时时间点成功。
定义SOAP错误
可以使用SOAPFault对象的方法为faultcode、 faultstring、和faultctor指定值。以下代码演示了SOAPFault对象的创建和faultcode、 faultstring、faultctor属性的设定。
SOAPFault fault;
reply = factory.createMessage();
envp = reply.getSOAPPart().getEnvelope(true);
someBody = envp.getBody();
fault = someBody.addFault():
fault.setFaultCode("Server");
fault.setFaultString("Some Server Error");
fault.setFaultActor("http://xxx.me.com/list/endpoint.esp/");
reply.saveChanges();
一旦发生服务器错误,服务器能够在对收到的SOAP消息做出的回应中,返回这个对象。
以下代码演示了如何定义一个detail和detail entry对象。注意,必须为detail entry对象创建一个名称。
SOAPFault fault = someBody.addFault();
fault.setFaultCode("Server");
fault.setFaultActor("http://foo.com/uri");
fault.setFaultString ("Unkown error");
DetailEntry entry = detail.addEntry(envelope.createName("125detail", "m", "Someuri");
entry.addTextNode("the message cannot contain the string //");
reply.saveChanges();
组装并部署SOAP服务
使用JAXM API和SAAJ API创建的应用被组装为web应用(WAR)或者基于J2EE平台的应用(EAR)。关于组装和部署web应用,请参见Sun ONE Application Server开发人员web应用指南。
客户端和服务示例
客户端和服务应用程序示例被捆绑在Sun ONE Application Server中。这些例子示范如何创建发送和接收XML消息的服务和客户端。你可以在下面的位置找到这些例子:
install_dir/samples/webservices/jaxm
install_dir/imq/demo/jaxm