java 如何读取 content-disposition 标头的内容?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7444104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I read the content of the content-disposition header?
提问by Gabriel Llamas
TEMPORARY SOLVED:InputStream closed in Apache FileUpload API
临时解决:Apache FileUpload API 中的 InputStream 已关闭
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
.
我想读取 content-disposition 标头的内容,但request.getHeader ("content-disposition")
总是返回 null 并且request.getHeader ("content-type")
只返回第一行,就像这样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.
EDIT1:我真正想解决的是当客户端发送超过最大大小的文件时的问题,因为当您调用 request.getPart ("something") 时,传递给它的部分名称并不重要,因为它总是会即使请求不包含此参数名称,也会抛出 IllegalStateException。
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.
我不能这样做,因为如果客户端发送的文件超过最大大小,对 getPart 的第一次调用将抛出异常(请参阅getPart() Javadoc),所以我不知道我收到了哪个文件。
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.
这就是为什么我想阅读内容处置标头的原因。我想读取参数“param”以了解哪个文件引发了异常。
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.
EDIT2:好吧,使用发布 Servlet 3.0 规范的 API,您无法控制前一种情况,因为如果文件引发异常,您将无法读取文件字段名称。这是使用包装器的不利部分,因为很多功能都消失了......此外,使用 FileUpload,您可以动态设置 MultipartConfig 注释。
If the file exceeds the maximum file size the api throws a FileSizeLimitExceededExceptionexception. The exception provides 2 methods to get the field name and the file name.
如果文件超过最大文件大小,api 将引发FileSizeLimitExceededException异常。异常提供了两种方法来获取字段名和文件名。
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)
但!!我的问题仍未解决,因为我想读取与文件一起以相同形式发送的另一个参数的值。(前面例子中“param”的值)
EDIT3: I'm working on this. As soon as I write the code I'll publish it here!
EDIT3:我正在研究这个。一旦我写了代码,我就会在这里发布!
回答by Vineet Reynolds
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.
request.getHeader ("content-disposition")
在您的情况下将返回 null,因为Content-Disposition
标头出现在 HTTP POST 正文中,因此需要单独处理它们。事实上,Content-Disposition
它只是一个有效的 HTTP 响应头。作为请求的一部分,它永远不会被视为标头。
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.
您最好使用像 Commons FileUpload 这样的文件上传库或 Servlet Spec 3.0 的内置文件上传功能来读取Content-Disposition
标头(间接)。实现 Servlet Spec 3.0 所需的文件上传功能所需的 Java EE 6 容器通常在幕后使用 Apache Commons FileUpload。
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.
如果您出于某种正当理由想忽略这些库,而是自己阅读标头,那么我建议您查看Apache Commons FileUpload 类的parseHeaderLine
和getParsedHeaders
方法FileUploadBase
。请注意,这些方法实际上是从与InputStream
关联的 中读取的HttpServletRequest
,并且您不能两次读取流。如果您想先读取Content-Disposition
代码中的标头,然后再使用 Apache Commons FileUpload 来解析请求,则必须将ServletRequestWrapper
包装原始请求的副本传递给 FileUpload API。逆序还要求您创建原始请求的副本并传递ServletRequestWrapper
将此副本包装到 FileUpload API。总的来说,这是一个糟糕的设计,因为在内存(或磁盘)中复制整个流只是为了读取请求正文两次是没有意义的。
回答by Phu Khong
Try to use part.getName()
尝试使用 part.getName()
Here is a sample.
这是一个示例。
Html file:
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
}
}