首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

让 SOAP 与 Web 服务器和平共处

让 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. 报告网络错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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 的目前形式而言,它还无能为力,不过就像这篇技巧所说明的那样,您可以绕过这一限制。
返回列表