【问题标题】:What causes a Java Servlet to print strings only with LF or with CRLF是什么导致 Java Servlet 仅使用 LF 或 CRLF 打印字符串
【发布时间】:2017-04-19 23:01:37
【问题描述】:

我在两台不同的服务器上运行相同的 Servlet。两台服务器都是 Linux Red Hat。

这个 Servlet 被一些 shell 脚本调用,这些脚本接收 Servlet 响应并使用它来做出一些决定。

问题是:Shell 脚本对不同类型的断线(LF 或 CRLF)非常敏感。在一个服务器中,Servlet 的输出带有 CRLF,而在另一台服务器中运行的 Servlet 的输出仅带有 LF。看:

服务器 1:

    0  \r  \n
 31 0d 0a

服务器 2:

 0  \n
  30  0a

这是打印结果的 Servlet 代码的一部分:

Integer authorization = checkAuthorization(error_code, sat);

if(authorization != null){
    out.println(authorization);
} 

如您所见,我从一个函数接收一个整数,然后打印它,仅此而已。

什么可以证明不同服务器中的这些不同输出是合理的?是否有任何环境变量可以控制它?

【问题讨论】:

  • 有一个依赖于平台的行分隔符的概念。请参阅stackoverflow.com/questions/207947/…,但这通常涵盖了 Unix 和 Windows 或 Mac 之间的区别。这会影响专门具有 println() 方法的打印编写器类型类。但是 servlet 不必使用这些。这取决于您的 servlet 如何创建输出。 IE。从现有文件加载数据。 / 使用 JSON /XML 库。代码是否隐式输出 CR LF 值?
  • 但您在回答中确实提到了 println,因此请查看与平台相关的行分隔符属性
  • 您是在寻找发生这种情况的原因,还是想要修改代码以确保它不会发生(包括跨平台)?
  • @slipperyseal 有可能,根据您的评论,我检查并注意到一台服务器在其 Tomcat 上使用 java 8,另一台服务器使用 java5,可能是由于不同的 JVM。我会尽快检查这个属性。
  • @Alex 现在我只想理解,因为当我不理解事物时我会感到不舒服。作为解决此问题的一种方法,我一直在使用“dos2unix”命令来删除 CR。但是问题是我的所有服务器中都没有“dos2unix”,所以我担心它将来会给我带来问题。不幸的是,我无法在服务器上安装新的二进制文件

标签: java linux shell servlets


【解决方案1】:

我假设您的代码示例中的outServletResponse.getWriter() 返回的编写器,它是PrintWriter

除非 servlet 容器对编写器实现进行修补,否则它应该使用由System.getProperty("line.separator") 返回的平台相关行分隔符。在 unix 系统上默认为\n

要解决您的问题,您可以首先检查受感染系统上System.getProperty("line.separator") 的值,如果它是 Windows 分隔符,则查找更改系统属性的代码或检查启动服务器的命令是否覆盖通过-D parameter 的系统属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多