如何读取content-disposition头部的内容?

5

临时解决方案:Apache FileUpload API中的InputStream关闭


我想读取content-disposition头的内容,但是request.getHeader("content-disposition")总是返回null,而request.getHeader("content-type")只返回第一行,例如multipart/form-data; boundary=AaB03x.
假设我收到以下头部:
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--

我想读取所有的内容分发头信息。怎么做?
谢谢。
编辑1:我真正想解决的问题是客户端发送的文件超过了最大大小限制,因为当您调用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),所以我无法知道我接收到了哪个文件。
这就是为什么我想读取content-disposition头部信息。我想读取参数“param”,以知道哪个文件抛出了异常。
编辑2: 好吧,使用发布Servlet 3.0规范的API,您无法控制前面的情况,因为如果文件引发异常,则无法读取文件字段名称。这是使用包装器的负面部分,因为许多功能消失了...还可以使用FileUpload动态设置MultipartConfig注释。

如果文件超过最大文件大小,API会抛出FileSizeLimitExceededException异常。该异常提供了2个方法来获取字段名称和文件名称。

但!!我的问题仍未解决,因为我想在同一表单中与文件一起发送的另一个参数的值。(前面示例中"param"的值)


编辑3: 我正在处理这个问题。一旦我编写好代码,我会在这里发布它!

2个回答

5

request.getHeader("content-disposition")在您的情况下将返回null,因为Content-Disposition标头出现在HTTP POST正文中,因此需要单独处理它们。实际上,Content-Disposition只是一个有效的HTTP响应标头。作为请求的一部分,它永远不会被视为标头。

您最好使用文件上传库(例如Commons FileUpload)或Servlet Spec 3.0的内置文件上传功能来间接读取Content-Disposition标头。Java EE 6容器需要实现Servlet Spec 3.0所需的文件上传功能,通常在后台使用Apache Commons FileUpload。

如果您出于某种有效的原因想忽略这些库并自己读取标头,则建议查看Apache Commons FileUpload的FileUploadBase类的parseHeaderLinegetParsedHeaders方法。请注意,这些方法实际上是从与HttpServletRequest相关联的InputStream中读取的,并且您不能两次读取流。如果您要首先在代码中读取Content-Disposition标头,然后稍后使用Apache Commons FileUpload解析请求,则必须传递一个ServletRequestWrapper,该包装器包装原始请求的副本到FileUpload API中。反向顺序也需要创建原始请求的副本并将包装此副本的ServletRequestWrapper传递给FileUpload API。总体而言,这是一个糟糕的设计,因为在内存(或磁盘)中复制整个流以便两次读取请求正文毫无意义。


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

注意:这仅适用于Servlet 3.0规范兼容的容器(例如,不适用于某些嵌入式Jetty版本)。 - Darrell Teague

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接