3

我有一个包含 823237 个字符的字符串。它实际上是一个 xml 文件,出于测试目的,我想作为响应形式返回一个 servlet。

我已经尝试了我能想到的一切

1)用整个字符串创建一个常量......在这种情况下Eclipse抱怨(在servlet类名下有一条红线) -

 The type generates a string that requires more than 65535 bytes to encode in Utf8 format in the constant pool

2) 将整个字符串分成 20 个字符串常量并直接写入out对象,例如:

out.println( CONSTANT_STRING_PART_1 + CONSTANT_STRING_PART_2 + 
             CONSTANT_STRING_PART_3 + CONSTANT_STRING_PART_4 +
             CONSTANT_STRING_PART_5 + CONSTANT_STRING_PART_6 + 
     // add all the string constants till .... CONSTANT_STRING_PART_20); 

在这种情况下……构建失败……抱怨……

   [javac] D:\xx\xxx\xxx.java:87: constant string too long
   [javac]      CONSTANT_STRING_PART_19 + CONSTANT_STRING_PART_20); 
                                                    ^

3) 将 xml 文件作为字符串读取并写入out object.. 在这种情况下我得到

SEVERE: Allocate exception for servlet MyServlet
Caused by: org.apache.xmlbeans.XmlException: error: Content is not allowed in prolog.

servlet最后我的问题是......我怎样才能从???返回这么大的字符串(作为响应) ?

4

6 回答 6

7

您可以避免使用流加载内存中的所有文本:

    InputStream is = new FileInputStream("path/to/your/file"); //or the following line if the file is in the classpath
    InputStream is = MyServlet.class.getResourceAsStream("path/to/file/in/classpath");
    byte[] buff = new byte[4 * 1024];
    int read;  
    while ((read = is.read(buff)) != -1) {  
        out.write(buff, 0, read);  
    }
于 2012-05-29T12:20:45.123 回答
4

第二种方法可能按以下方式工作:

out.print(CONSTANT_STRING_PART_1);
out.print(CONSTANT_STRING_PART_2);
out.print(CONSTANT_STRING_PART_3);
out.print(CONSTANT_STRING_PART_4);
// ...
out.print(CONSTANT_STRING_PART_N);
out.println();

您当然可以循环执行此操作(强烈推荐;))。

你这样做的方式,你只是暂时再次创建大字符串,然后将它传递给println(),这与第一个问题相同。

于 2012-05-29T12:14:50.507 回答
2

绳索:理论与实践

为什么以及何时使用 Ropes for Java 进行字符串操作

于 2012-05-29T12:43:13.847 回答
1

您可以将 823K 文件读入字符串。也许不是最优雅的方法,但完全可行。方法3应该有效。有一个 XML 错误,但这与从文件读取到字符串或数据长度无关。

但是,它必须是一个外部文件,因为它太大而无法内联到类文件中(这些文件有大小限制)。

我推荐 Commons IO FileUtils#readFileToString

于 2012-05-29T12:05:24.430 回答
1

您必须处理ByteArrayOutputStream而不是自身的 String。如果您想在 http 响应中发送您的字符串,您所要做的就是从该 byteArray 流中读取并写入响应流,如下所示:

ByteArrayOutputStream baos = new ByteArrayOutputStream(8232237);
baos.write(constant1.getBytes());
baos.write(constant2.getBytes());
...
baos.writeTo(response.getOutputStream());
于 2012-05-29T12:08:06.577 回答
0

问题 1) 和 2) 都是由于相同的基本问题。字符串文字(或常量字符串表达式)不能超过 65535 个字符,因为类文件格式中的字符串常量有硬性限制。

第三个问题听起来像是您实现它的方式中的一个错误,而不是一个基本问题。事实上,听起来您正在尝试将 XML 作为 DOM 加载,然后对其进行解析(这是不必要的),并且您设法在此过程中破坏了 XML。(或者它可能在您尝试读取的文件中被破坏......)

简单而优雅的解决方案是将内容保存在文件中,然后以纯文本形式读取。

或者......不太优雅,但同样有效:

   String[] strings = new String[](
        "longString1",
        "longString2",
        ...
        "longStringN"};

   for (String str : strings) {
       out.write(str);
   }

当然,将测试数据嵌​​入为字符串文字的问题在于,您必须转义字符串中的某些字符才能让编译器满意。如果您必须手动完成,那将很乏味。

于 2012-05-29T12:07:50.650 回答