项目迁移:将 Java Web应用 从Windows迁移到AIX需注意问题(一)----HTTP通信问题

HTTP 通信问题

HTTP 通信在每种 Web 应用程序中都非常普遍。每当调用某个 Servlet 或 JavaServer Pages (JSP),就会发生 HTTP 通信。虽然 HTTP 协议是平台无关的,但是在不同平台之间通信时需要注意一些特殊的事项。

在本场景中,一个客户端对网关发起一个特殊请求,网关处理该请求,然后向客户端发回一个响应。该客户端使用基于 XML 的专有协议来与网关通信,并且网关仅处理遵守该协议的消息。该协议在 <Name> 和 <Greeting> 这两个 XML 元素之间需要一个换行符。

如清单 1 中的代码所示,该请求的正文添加了一个换行符。但是,服务器是否顺利地处理它并正确地响应呢?视情况而定。这是在跨不同平台移植 Java 应用程序时的一个常见问题。


清单 1. 客户端发出一个 HTTP 请求

try {
  URL url = new URL("http://localhost:9081/SampleWeb/Simulator");
  URLConnection conn = url.openConnection();
  conn.setDoOutput(true);
  conn.setRequestProperty("Content-Type", "application/xml");

  OutputStream os = conn.getOutputStream();
  PrintWriter writer = new PrintWriter(os);

  writer.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>");
  writer.println("<Name>");
  writer.print("<first name>");
  writer.print(“Rachel");
  writer.println("</first name>");
  writer.println("</Name>");

  //A line break is required here
  writer.println();

  writer.println("<Greeting>");
  writer.println("Hello!");
  writer.println("</Greeting>");

  writer.flush();
  conn.getInputStream();
} catch (MalformedURLException mue) {
  System.err.println("error, message =" + mue);
} catch (IOException ioe) {
  System.err.println("error, message =" + ioe);
}


陷阱
该代码在 Windows 上的开发环境中工作得很好,但是在部署到 AIX 上的生产环境中以后,您会惊奇地发现网关没有返回任何响应。那么这段似乎正确的代码出了什么问题呢?
不在您的控制之内的网关是一个运行于 Windows 平台上的 C 程序。它错误地假设所有接收到的请求都来自 Windows,并且 \r\n 换行符应该位于 <Name> 和 <Greeting> 元素之间。因此,它尝试将该请求分析为在 <Name> 和 <Greeting> 之间具有一个 \r\n 字符。然而,在 AIX 和大多数类 UNIX 平台上,如果没有预先设置 line.separator Java 系统属性变量,则其缺省值为 \n,这就是网关抱怨请求格式不正确的原因。

解决办法
一旦您知道了出错的原因,解决此问题是相当简单的。可以在客户端或网关代码中进行修复。
如果您无法控制网关代码,则只能使用 “System.setProperty(“line.separator", "\r\n")" ; 对客户端进行硬编码。
否则,应该让网关代码以适当的方式处理不同的平台。对于类 UNIX 平台,可以将 \n 字符处理为换行符。对于 Mac OS,应该将 \r 处理为换行符。在 Windows 平台上,应该将 \r\n 处理为换行符。
提醒
要注意 Java 应用程序编程接口 (API),例如 java.io.Writer、java.io.Reader 和继承它们的 API。它们全都是基于字符的 API,并且在没有设置行分隔符时,它们将从系统属性获得缺省行分隔符值。如果不需要严格的字符格式,您应该考虑使用基于字节的 Java API 以实现更好的性能。
当在不同平台之间移植时,硬编码平台相关的内容通常是 Java 应用程序失去兼容性的原因之一。行分隔符只是最常见的常量之一。可能的内容还包括文件分隔符、路径分隔符,等等。当您希望在代码中包括这些常量时,应该使用 System.getProperty("property name") 来获得属性值而不是硬编码该字符。

你可能感兴趣的:(java,windows,Web,应用服务器,AIX)