Как я могу прочитать содержимое заголовка content-disposition? - PullRequest
6 голосов
/ 16 сентября 2011

ВРЕМЯ РЕШЕНО: InputStream закрыт в Apache FileUpload API


Я хочу прочитать содержимое заголовка расположения содержимого, но request.getHeader ("content-disposition") всегдаreturn null и request.getHeader ("content-type") возвращает только первую строку, например multipart/form-data; boundary=AaB03x.

Предположим, я получаю следующий заголовок:

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="submit-name"

Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--AaB03x--

Я хочу прочитать все заголовки размещения содержимого,Как?

Спасибо.


EDIT1 : что я действительно хочу решить, так это проблему, когда клиент отправляет файл, размер которого превышает максимальный, потому что, когда выВызовите request.getPart («что-то»), не имеет значения, какое имя части вы передаете ему, потому что оно всегда вызовет IllegalStateException, даже если запрос не содержит этого имени параметра.

Пример:

Part part = request.getPart ("param");
String value = getValue (part);
if (value.equals ("1")){
    doSomethingWithFile1 (request.getPart ("file1"))
}else if (value.equals (2)){
    doSomethingWithFile2 (request.getPart ("file2"))
}

private String getValue (Part part) throws IOException{
    if (part == null) return null;

    BufferedReader in = null;
    try{
        in = new BufferedReader (new InputStreamReader (part.getInputStream (), request.getCharacterEncoding ()));
    }catch (UnsupportedEncodingException e){}

    StringBuilder value = new StringBuilder ();
    char[] buffer = new char[1024];
    for (int bytesRead; (bytesRead = in.read (buffer)) != -1;) {
        value.append (buffer, 0, bytesRead);
    }

    return value.toString ();
}

Я не могу этого сделать, потому что, если клиент отправляет файл, размер которого превышает максимальный, первый вызов getPart вызовет исключение (см. getPart () Javadoc ), поэтому я могуНе знаю, какой файл я получил.

Вот почему я хочу прочитать заголовки размещения контента.Я хочу прочитать параметр "param", чтобы узнать, какой файл вызвал исключение.


EDIT2 : Ну, с API, который публикует спецификацию Servlet 3.0, вы не можетеуправляйте предыдущим случаем, потому что, если файл выдает исключение, вы не можете прочитать имя поля файла.Это отрицательная часть использования оболочки, поскольку многие функции исчезают ... Также с помощью FileUpload вы можете динамически устанавливать аннотацию MultipartConfig.

Если размер файла превышает максимальный размер файла, который API выдает FileSizeLimitExceededException исключение.Исключение предоставляет 2 метода для получения имени поля и имени файла.

Но !!Моя проблема до сих пор не решена, потому что Я хочу прочитать значение другого параметра, отправленного вместе с файлом в той же форме. (значение «param» в предыдущем примере)


EDIT3 : я работаю над этим.Как только я напишу код, я опубликую его здесь!

Ответы [ 2 ]

5 голосов
/ 16 сентября 2011

request.getHeader ("content-disposition") вернет ноль в вашем случае, так как заголовки Content-Disposition появляются в теле HTTP POST, что требует их обработки отдельно.Фактически, Content-Disposition является только действительным заголовком ответа HTTP.Как часть запроса, он никогда не будет рассматриваться как заголовок.

Вам лучше использовать библиотеку загрузки файлов, такую ​​как Commons FileUpload, или встроенные функции загрузки файлов Servlet Spec 3.0 для чтениязаголовок Content-Disposition (косвенно).Контейнеры Java EE 6, необходимые для реализации функции выгрузки файлов, требуемой в Servlet Spec 3.0, часто используют Apache Commons FileUpload изнутри.

Если вы хотите по какой-то уважительной причине игнорировать эти библиотеки и вместо этого прочитатьсами заголовки, тогда я бы порекомендовал взглянуть на parseHeaderLine и getParsedHeaders методы класса FileUploadBase Apache Commons FileUpload.Обратите внимание, что эти методы действительно читают из InputStream, связанного с HttpServletRequest, и вы не можете прочитать поток дважды.Если вы хотите сначала прочитать заголовок Content-Disposition в своем коде, а затем использовать Apache Commons FileUpload для разбора запроса, вам нужно будет передать ServletRequestWrapper, который упаковывает копию оригинального запроса в API-интерфейс FileUpload.Обратная последовательность также требует, чтобы вы создали копию исходного запроса и передали ServletRequestWrapper, обертывающий эту копию, в FileUpload API.В целом это плохой дизайн, так как нет смысла реплицировать весь поток в памяти (или на диске) только для чтения тела запроса дважды.

1 голос
/ 20 июля 2012

Попробуйте использовать part.getName()

Вот пример.

HTML-файл:

<form action="UploadServlet" method="post" enctype="multipart/form-data">
    <input type="text" value="phu" name="info">
    <input type="file" name="file1"/> <input type="submit"/>
</form>

Сервлет:

String field;

for (Part part : request.getParts()) {
    field = part.getName();
    if (field.equals("info")) {
        // Your code here
    } else if (field.equals("file1")) {
        // Your code here
    }
}
...