代码之家  ›  专栏  ›  技术社区  ›  Redwood

通过Java转义XHTML网页上显示的大量字符

  •  0
  • Redwood  · 技术社区  · 15 年前

    当收到由我的应用程序处理的网页请求时,在我的代码中调用一个方法,该方法包含请求的所有信息,包括显示网页的输出流。

    在我的一个页面上,我想显示一个(日志)文件,大小可达1 MB。

    我可以使用以下代码显示此文件:

    final PrintWriter writer; // Is initialized to a PrintWriter writing to the output stream.
    final FileInputStream fis = new FileInputStream(file);
    final InputStreamReader inputStreamReader = new InputStreamReader(fis);
    try {
        writer.println("<div id=\"log\" style=\"white-space: pre-wrap; word-wrap: break-word\">");
        writer.println("    <pre>");
        int length;
        char[] buffer = new char[1024];
        while ((length = inputStreamReader.read(buffer)) != -1) {
            writer.write(buffer, 0, length);
        }
        writer.println("    </pre>");
        writer.println("</div>");
    } finally {
        if (inputStreamReader != null) {
            inputStreamReader.close();
        }
    }
    

    这相当有效,并在一两秒钟内(一个可接受的时间范围)显示整个文件。

    这个文件可以(实际上确实)包含无效的XHTML字符,最常见的是 <>

    我首先尝试的是一个CDATA部分,但如文档所示 here

    我尝试的第二个方法如下:

    // Based on code: https://stackoverflow.com/questions/439298/best-way-to-encode-text-data-for-xml-in-java/440296#440296
    // Modified to write directly to the stream to avoid creating extra objects.
    private static void writeXmlEscaped(PrintWriter writer, char[] buffer, int offset, int length) {
        for (int i = offset; i < length; i++) {
            char ch = buffer[i];
    
            boolean controlCharacter = ch < 32;
            boolean unicodeButNotAscii = ch > 126;
            boolean characterWithSpecialMeaningInXML = ch == '<' || ch == '&' || ch == '>';
    
            if (characterWithSpecialMeaningInXML || unicodeButNotAscii || controlCharacter) {
                writer.write("&#" + (int) ch + ";");
            } else {
                writer.write(ch);
            }
        }
    }
    

    这会正确地转义字符(如果需要,我会将其展开以转义HTML无效字符),但网页随后需要15秒以上的时间来显示,页面上的其他资源(图像、css样式表)间歇性地无法加载(我相信是由于处理器被挂起而导致请求超时)。

    我试过用 BufferedWriter PrintWriter 以及更改缓冲区大小(用于读取文件和 )以各种方式,没有任何改进。

    有没有一种方法可以转义所有不需要遍历流中每个字符的XHTML无效字符?如果失败了,有没有办法加速我的代码,使其足以在几秒钟内显示这些文件?

    如果必须的话,我会考虑减小日志文件的大小,但我希望使它们的大小至少为250-500 KB(理想情况下为1 MB)。

    我已经有了一个简单下载日志文件的方法,但是我想在浏览器中显示它们,以便进行简单的故障排除/阅读。


    编辑:

    在制作了 change

    我可能只需要减小日志文件的最大大小。

    3 回复  |  直到 8 年前
        1
  •  1
  •   Cameron Skinner    15 年前

    一个小的改变会(嗯,可能)显著提高速度是改变

    writer.write("&#" + (int) ch + ";");
    

    writer.write("&#");
    writer.write((int)ch);
    writer.write(";");
    

    编辑:对另一个答案的一个评论是高度相关的:先找到慢的那一位。我建议测试没有要转义的字符和许多要转义的字符的日志。

    我认为你无论如何都应该做出建议的改变,因为它只花了你几秒钟的时间。

        2
  •  1
  •   Bozho    15 年前

    StringEscapeUtils 来自commons lang:

    StringEscapeUtils.escapeHtml(writer, string);
    
        3
  •  1
  •   Jacob    15 年前

    iframe 托管在您的网页内。这个 框架 的源可以指向将内容用作文本的URL。

    推荐文章