3

823237 文字の文字列があります。実際にはxmlファイルであり、テスト目的で、サーブレットからの応答として返したいと考えています。

考えられる限りのことはすべて試しました

1)文字列全体で定数を作成します...この場合、Eclipseは文句を言います(サーブレットクラス名の下に赤い線があります)-

 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

2 番目のアプローチは、次のように機能する可能性があります。

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

String 自体ではなく、ByteArrayOutputStreamを処理する必要があります。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 文字を超えることはできません。

3 番目の問題は、根本的な問題ではなく、実装方法のバグのように聞こえます。実際、XML を DOM として読み込んで解析を解除しようとしているように思えます (これは不要です)。(または、読み込もうとしているファイルで破損している可能性があります...)

シンプルで洗練された解決策は、内容をファイルに保存してからプレーンテキストとして読み取ることです。

または...エレガントではありませんが、同じくらい効果的です:

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

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

もちろん、テスト データを文字列リテラルとして埋め込む際の問題は、コンパイラを満足させるために、文字列内の特定の文字をエスケープする必要があることです。手作業だと面倒ですよね。

于 2012-05-29T12:07:50.650 に答える