TEMPORARY已解决: InputStream closed in Apache FileUpload API
我想阅读内容处置标题的内容,但request.getHeader ("content-disposition")
始终返回null,而request.getHeader ("content-type")
只返回第一行,例如multipart/form-data; boundary=AaB03x
。
Supose我收到以下标题:
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(“something”)时无关紧要您传递给它的部件名称,因为即使请求不包含此参数名称,它也会抛出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 :嗯,使用发布Servlet 3.0规范的API,您无法控制之前的情况,因为如果文件抛出异常,则无法读取文件字段名称。这是使用包装器的负面部分,因为许多功能都消失了......同样使用FileUpload,您可以动态设置MultipartConfig注释。
如果文件超过最大文件大小,则api会抛出FileSizeLimitExceededException异常。该异常提供了两种获取字段名称和文件名的方法。
但是!!我的问题仍未解决,因为 我想读取与该文件一起发送的另一个参数的值。 (前一个“param”的值例如)
EDIT3 :我正在研究这个问题。一旦我编写代码,我就会在这里发布它!
答案 0 :(得分:5)
request.getHeader ("content-disposition")
将在您的情况下返回null,因为Content-Disposition
标题出现在HTTP POST正文中,因此需要单独处理它们。实际上,Content-Disposition
只是一个有效的HTTP响应头。作为请求的一部分,它永远不会被视为标题。
最好使用Commons FileUpload等文件上传库或Servlet Spec 3.0的内置文件上传功能来读取Content-Disposition
标题(间接)。实现Servlet Spec 3.0所需的文件上载功能所需的Java EE 6容器通常使用Apache Commons FileUpload。
如果您想出于某些正当理由忽略这些库而是自己阅读标题,那么我建议您查看Apache的FileUploadBase
类的parseHeaderLine
和getParsedHeaders
方法Commons FileUpload。请注意,这些方法实际上是从与InputStream
关联的HttpServletRequest
中读取的,并且您无法读取该流两次。如果您想首先阅读代码中的Content-Disposition
标头,然后使用Apache Commons FileUpload来解析请求,那么如果原始请求发送到FileUpload,则必须传递包含副本的ServletRequestWrapper
API。反向序列还要求您创建原始请求的副本,并将ServletRequestWrapper
包装此副本传递给FileUpload API。总的来说,这是糟糕的设计,因为在内存(或磁盘)上复制整个流只是为了读取请求体两次是没有意义的。
答案 1 :(得分:1)
尝试使用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>
的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
}
}