Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I read the content of the content-disposition header?

TEMPORARY SOLVED: InputStream closed in Apache FileUpload API


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

Supose I receive 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-disposition headers. How?

Thanks.


EDIT1: What I really want to solve is 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 throw 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 can't do this because if the client sends a file that exceeds the max size the first call to getPart will throw the exception (see getPart() Javadoc), so I can't know which file I've received.

That's why I want to read the content-disposition headers. I want to read the parameter "param" to know which file has thrown the exception.


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

If the file exceeds the maximum file size the api throws a FileSizeLimitExceededException exception. The exception provides 2 methods to get the field name and the file name.

But!! my problem is not still solved because I want to read the value of another parameter sent together with the file in the same form. (the value of "param" in the previous example)


EDIT3: I'm working on this. As soon as I write the code I'll publish it here!

like image 954
Gabriel Llamas Avatar asked Sep 16 '11 11:09

Gabriel Llamas


People also ask

How do you use content-disposition headers?

In a regular HTTP response, the Content-Disposition response header is a header indicating if the content is expected to be displayed inline in the browser, that is, as a Web page or as part of a Web page, or as an attachment, that is downloaded and saved locally.

What is content type and content-disposition?

Content-Disposition takes one of two values, `inline' and `attachment'. 'Inline' indicates that the entity should be immediately displayed to the user, whereas `attachment' means that the user should take additional action to view the entity.

How do you set a content-disposition header in Python?

header dict get set passing headers=fh with 'Content-Disposition':.... Calling rf. make_multipart(content_type=ft) , at the next line, only passing the 3trd tuple item. def make_multipart( self, content_disposition=None, content_type=None, content_location=None ): self.

What is content-disposition in Java?

The MIME Content-disposition header provides presentation information for the body-part. It is often added to attachments specifying whether the attachment body part should be displayed (inline) or presented as a file name to be copied (attachment).


2 Answers

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

You're better off using a file upload library like Commons FileUpload or the in-built file-upload features of the Servlet Spec 3.0 to read the Content-Disposition header (indirectly). Java EE 6 containers that are required to implement the file-upload functionality required of Servlet Spec 3.0, often use Apache Commons FileUpload under the hood.

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

like image 63
Vineet Reynolds Avatar answered Nov 15 '22 12:11

Vineet Reynolds


Try to use part.getName()

Here is a sample.

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
    }
}
like image 26
Phu Khong Avatar answered Nov 15 '22 12:11

Phu Khong