如何阅读内容处置标题的内容?

时间:2011-09-16 11:36:42

标签: java servlets http-headers multipart

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 :我正在研究这个问题。一旦我编写代码,我就会在这里发布它!

2 个答案:

答案 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类的parseHeaderLinegetParsedHeaders方法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
    }
}