2012-05-29 4 views
2

У меня есть строка, в которой есть 823237 символов. его на самом деле xml-файл и для целей тестирования я хочу вернуть в качестве формы ответа сервлет.Как обработать строку с 823237 символами

Я попробовал все, что я могу возможно думать о

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 ???

+0

я сделал с StringBuffer, но опять-таки сборка завершается с ошибкой, и я получаю ту же ошибку, что и 2, –

+0

Обратите внимание, что String + String создает новую строку ;-) –

+0

В документе XML не должно быть пробела или пробела или элемента xml перед проломом ' '. –

ответ

3

Второй подход может работать следующим образом:

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(), что является той же проблемой, что и первая.

1

Вы можете прочитать файл 823K в строку. Возможно, это не самый элегантный метод, но вполне выполнимый. Метод 3 должен был работать. Была ошибка XML, но это не имеет ничего общего с чтением из файла в String или длиной данных.

Это должен быть внешний файл, хотя он слишком велик, чтобы быть встроенным в файл класса (для этого существуют ограничения по размеру).

Я рекомендую Commons IO FileUtils#readFileToString.

+0

, но я читаю файл как строку справа? то почему ошибка xml? Я не пытаюсь разобрать его на этом этапе? как только выполняется вызов сервлета. вызывающий класс печатает это исключение в консоли! –

+0

Вы определенно получаете ошибку синтаксического анализа XML. – Thilo

+0

проблема 3 из-за ошибки в вашем xml. Может быть какое-то пустое пространство или строка перед '

0

Обе проблемы 1) и 2) связаны с одной и той же фундаментальной проблемой. Строковый литерал (или постоянное выражение String) не может превышать 65535 символов, потому что существует жесткий предел строковых констант в формате файла класса.

Третья проблема звучит как ошибка в том, как вы ее реализовали, а не как фундаментальную проблему. На самом деле, похоже, вы пытаетесь загрузить XML как DOM, а затем не разбираетесь в нем (что необязательно), и вам почему-то удалось манипулировать XML в процессе. (Или, может быть, это искалечено в файле, который вы пытаетесь прочитать ...)

Простым и изящным решением является сохранить материал в файле, а затем прочитать его как обычный текст.

... Или менее элегантно, но столь же эффективным:

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

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

Конечно, проблема с вложением тестовых данных в виде строковых литералов, что вы должны избежать определенных символов в строке, чтобы компилятор счастливый. Это утомительно, если вам нужно сделать это вручную.

+0

как я могу это сделать? –

1

Вы должны иметь дело с ByteArrayOutputStream, а не с самим String.Если вы хотите, чтобы отправить строку в ответ HTTP все, что вам нужно сделать, это прочитать из этого ByteArray, потока и запись в поток ответа, как это:

ByteArrayOutputStream baos = new ByteArrayOutputStream(8232237); 
baos.write(constant1.getBytes()); 
baos.write(constant2.getBytes()); 
... 
baos.writeTo(response.getOutputStream()); 
+0

не могли бы вы дать немного более подробно ... вы говорите, что я должен попытаться написать массив символов для объекта out? –

+0

ok вы создаете экземпляр ByteArrayOutputStream и объявляете его размер 823237 в конструкторе. то вы записываете свои константы один за другим, используя byteArrayStream.write (constant.getBytes()) –

5

Вы можете избежать, чтобы загрузить весь текст в памяти с помощью потоков:

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); 
    }