How can I read the contents of the content header?

WORKAROUND: InputStream closed in Apache FileUpload API


I want to read the contents of the content-disposition header, but request.getHeader ("content-disposition") always returns null, and request.getHeader ("content-type") returns only the first row, such as multipart/form-data; boundary=AaB03x multipart/form-data; boundary=AaB03x .

Suppose I get the following header:

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

I want to read all the content headers. How?

Thanks.


EDIT1 . I really want to solve the problem when the client sends a file that exceeds the maximum size, because when you call request.getPart ("something"), it doesn’t matter what part name you pass to it, because it always will raise an IllegalStateException, even if the request does not contain this parameter name.

Example:

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

I cannot do this because if the client sends a file that exceeds the maximum size, the first call to getPart will throw an exception (see getPart () Javadoc ), so I cannot know which file I received.

This is why I want to read the content headers. I want to read the param parameter to find out which file raised the exception.


EDIT2 . Well, with the API that publishes the Servlet 3.0 specification, you cannot control the previous case, because if the file throws an exception, you cannot read the file field name. This is the negative part of using a wrapper because many functions disappear ... Also, with FileUpload you can dynamically set the MultipartConfig annotation.

If the file exceeds the maximum file size, api throws a FileSizeLimitExceededException . The exception provides 2 methods for getting the field name and file name.

But!! my problem has not yet been solved, because I want to read the value of another parameter sent along with the file in the same form. (value "param" in the previous example)


EDIT3 . I'm working on it. As soon as I write the code, I will publish it here!

+6
source share
2 answers

request.getHeader ("content-disposition") will return null in your case, as the Content-Disposition headers are displayed in the HTTP POST block, thereby requiring them to be processed separately. In fact, Content-Disposition is only a valid HTTP response header. As part of the request, it will never be considered as a header.

You are better off using a library to upload files, such as Commons FileUpload, or the Servlet Spec 3.0 built-in file upload functions to read the Content-Disposition header (indirectly). Java EE 6, which is required to implement the file upload function required by Servlet Spec 3.0, often uses Apache Commons FileUpload under the hood.

If you want to ignore these libraries for some good reason and instead read the headers yourself, I would recommend looking at the parseHeaderLine and getParsedHeaders FileUploadBase of the Apache Commons FileUpload class. Note that these methods are actually read from the InputStream associated with the HttpServletRequest , and you cannot read the stream twice. If you first want to read the Content-Disposition header in your code, and then use Apache Commons FileUpload to parse the request, you will have to pass ServletRequestWrapper , which wraps the copy if the original request is a FileUpload API. The reverse sequence also requires that you create a copy of the original request and pass ServletRequestWrapper , assuring the copy in the FileUpload API. In general, this is a bad design, since it makes no sense to copy the entire stream in memory (or on disk) just to read the request body twice.

+5
source

Try using part.getName()

Here is an example.

Html file:

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

Servlet:

 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 } } 
+1
source

Source: https://habr.com/ru/post/897462/


All Articles