IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML  >

技巧: 让 SOAP 与 Web 服务器和平共处

如果服务器认为 Web 服务就是 Web

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 中级

Benoit Marchal (bmarchal@pineapplesoft.com), 顾问, Pineapplesoft

2003 年 3 月 01 日

SOAP 的强大之处在于它建立在为人熟知而又广泛部署的 Web 基础设施上。但这也可能成为一个弱点,因为可能要求 Web 服务器支持完全不存在的 Web 服务。 在本期中,Benoit 讨论了 Web 服务中错误处理的一些问题。

两年以前,我走进了 developerWorksSoapbox ,表明我对当时新生的协议 SOAP 感兴趣。我的主要观点是,您必须喜欢 SOAP,因为它向人们熟知的 Web 基础设施增加了有用的服务。

现在 SOAP 已经成为正式的 W3C 推荐标准,我也有了实际应用它的经验。总的来说,这些经验验证了我当初的印象,即建立在 Web 基础设施上是一种好的做法。唯一的问题是 Web 还没有感知到 SOAP。这篇技巧展示了在使用 SOAP 时可能要避开的一些缺陷。

这儿没有人

SOAP 规定如果服务器遇到错误应该返回一个 SOAP 错误码。但是服务器是为浏览器、错误配置和网络问题设计的,返回的更有可能是 HTTP 错误而不是 SOAP 错误码。

您也许会想“ 管它呢?只要正确配置服务器就行了。”但是如果说我的个人经验对您有所启发的话,您就必须考虑这一点。在 2001-2002 期间我所工作过的那些项目(即稳定的项目)中,80% 的支持请求都是基础设施问题。

多数问题都可以追踪到 Internet 连接和用户站点上的代理。有时候,似乎代理、NAT(网络地址转换)、DNS(域名服务器)和防火墙联合起来对付 Web 服务。本地网络管理员可能改变了一个参数,从而导致服务不能访问。

面对网络错误,多数 Web 服务客户报告的都是莫名其妙的胡言乱语 —— 可能是异常跟踪。如果用户遇到异常跟踪,他会打电话找 ,而不是他的网络管理员。

更糟的是,在开发期间您不大可能遇到这种问题,仅仅是因为开发服务器通常就位于本地网络中。





回页首


告诉他们

如果说在过去两年中构建 Web 服务得到什么教训的话,那就是发出含义明确的网络错误消息。

悲哀的是,JAX-RPC 没有什么帮助。事实上,JAX-RPC 在报告任何错误时做的工作都很少, SOAPException 异常甚至没有返回 SOAP 错误码、字符串或者详细信息的方法。除非这种情况得到改变,否则您最大的希望就是遍历异常链,直到发现错误的更明确描述。

异常链

异常链是 JDK 1.4 中引入的。它定义了从错误的根源检索信息的方法。





回页首


Apache 有帮助吗?

Apache Axis 是最流行的 SOAP 库之一,在 Java 异常链中为多数网络错误建立了专有的 AxisFault 异常。这种异常允许您检索有用的诊断信息,包括错误码和字符串。

如果这个库遇到由于代理或者服务器配置不当造成的 HTTP 错误,它就把错误码设为 {http://xml.apache.org/axis/}HTTP 。这个码是 Axis 专用的(就像名称空间 URI 所表明的那样),但总比什么也没有好。Axis 1.2 (撰写本文时处于 alpha 测试状态)更进了一步,在错误细节中返回 HTTP 错误。

如果这个库遇到由于 NAT 或者 DNS 不当配置造成的 HTTP 错误,Axis 就把错误码设为 Server.userException 。尽管 Server 类属于 SOAP 标准,但 userException 是一个扩展子码。

清单 1 中的示例代码解释 Axis 返回的 SOAPException 异常,并合情合理地打印意义明确的错误消息。清单 1 只能用于 Axis(已经用 Axis 1.1 和 1.2 alpha 版测试过),但是除非错误报告已经证明是在 JAX-RPC 中,您就只能使用这种特定于库的专用码。


清单 1. 报告网络错误
public void printSOAPException(SOAPException x)
{
 Throwable cause = x.getCause();
 if(cause != null && cause instanceof AxisFault)
   printAxisFault((AxisFault)cause);
 else if(cause != null)
   System.out.println(x.getClass().getName()
                     + " exception chained: "
                     + x.getMessage());
 else
   System.out.println("SOAP exception: " + x.getMessage());
}
public void printAxisFault(AxisFault x)
{
 // tested with Axis 1.1 & Axis 1.2 alpha
 if(x.getFaultCode().equals(new QName("http://xml.apache.org/axis/","HTTP")))
 {
   Element e =
      x.lookupFaultDetail(
        new QName("http://xml.apache.org/axis/","HttpErrorCode"));
   if(null != e)
   {
      e.normalize();
      String httpErrorCode = e.getFirstChild().getNodeValue().trim();
      if(httpErrorCode.equals("407"))
         System.out.println("Proxy password incorrect");
      else if(httpErrorCode.equals("502") || httpErrorCode.equals("504"))
         System.out.println("Proxy cannot find the server");
      else if(httpErrorCode.equals("500"))
         System.out.println("Proxy or server unavailable");
      else if(httpErrorCode.equals("404"))
         System.out.println("No Web service (404 File Not Found)");
      else
         System.out.println(x.getFaultString());
   }
   else
      System.out.println("Network error: " + x.getFaultString());
 }
 else if(x.getFaultCode().equals(
          new QName("http://schemas.xmlsoap.org/soap/envelope/",
                    "Server.userException")))
  System.out.println("Most likely a net error: " + x.getFaultString());
 else
  System.out.println("SOAP Fault: " + x.getFaultCode() + ", " 
                    + x.getFaultString());
}





回页首


结束语

如果不想您的电话因为网络配置不当而响个不停,一定要让 Web 服务客户返回合理的网络错误消息。就 JAX-RPC 的目前形式而言,它还无能为力,不过就像这篇技巧所说明的那样,您可以绕过这一限制。



参考资料



关于作者

Author photo

Benoit Marchal 是一位比利时籍顾问。他是 XML by Example, Second Edition 以及其他几本 XML 书籍的作者。他主要从事 XML、Java 技术和电子商务方面的工作。关于本主题的更多信息,请参阅 www.marchal.com。可以通过 bmarchal@pineapplesoft.com和他联系。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款