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 si开发者_如何学JAVAze 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!
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.
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
}
}
精彩评论