首页 > 解决方案 > 使用在 LINUX 中运行的 windows 换行符生成 xml 签名

问题描述

首先,对不起我的英语不好!

我必须对一些 XML 文档进行数字签名以发送给智利 SII,包括其中的数字签名。当我在Windows的JAVA下开发时,我可以发送文档并获得 OK 作为响应。作为 POST 发送的文档,包括 XML 消息之前的一些标头。如果我使用\r\n作为换行符,则响应正常,如果我只使用\n,我会收到 HTTP 500 响应。所以我决定使用\r\n

下一步是将我的程序编译并打包到一个 jar 中,然后将它放在Linux Server中。当我执行程序并发送文档时,如果我使用\n换行符,我会收到一个 HTTP 500 响应,这与我在 Windows 中收到的响应相同。如果我使用\r\n,我可以发送 xml,但我从服务器收到一条错误消息:“XML 文档结构必须在同一个实体内开始和结束。” 我可以看到 Windows 中已签名的 XML 和 Linux 中已签名的 XML 之间的独特区别是换行符。就像服务器期望\r\n一样,它在 Windows 中使用,但是当我在 Linux 中执行它时,它使用\n作为 line-break 。

我可以在我的 java 代码中添加一些神奇的句子来强制使用 \r\n 作为换行符,即使我在 Linux 下执行它也是如此?

注意:我正在使用 java7 和加密库形成签名。

标签: javaxmllinuxxml-signature

解决方案


如果您使用 PrintWriter 生成发布请求 - 特别是它的println()调用 - 您可以覆盖 PrintWriter 以使其使用您希望的换行符分隔符,如下所示:

static PrintWriter newPrintWriter(Writer out, String lineSep)
{
    return new PrintWriter(out) {
        public void println() {
            print(lineSep);
        }
    };
}

然后,您可以使用类似这样的 Unix/Linux 行分隔符来包装邮政编码的输出流:

try(PrintWriter out = newPrintWriter(yourOutputStream, "\n")) {
   out.println("whatever");
}

或对于 Windows 样式的行分隔符:

try(PrintWriter out = newPrintWriter(yourOutputStream, "\r\n")) {
   out.println("whatever");
}

推荐阅读