2011-09-16 51 views
6

TẠM SOLVED:InputStream closed in Apache FileUpload APILàm cách nào để đọc nội dung của tiêu đề bố cục nội dung?


Tôi muốn đọc nội dung của tiêu đề Content-Disposition nhưng request.getHeader ("content-disposition") luôn trả về null và request.getHeader ("content-type") chỉ trả lại dòng đầu tiên, như multipart/form-data; boundary=AaB03x này.

Giả sử tôi nhận tiêu đề sau đây:

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

Tôi muốn đọc tất cả các tiêu đề nội dung bố trí. Làm sao?

Cảm ơn.


EDIT1: Những gì tôi thực sự muốn giải quyết vấn đề là khi khách hàng gửi một tập tin mà vượt quá kích thước tối đa vì khi bạn gọi request.getPart ("cái gì đó") nó không có vấn đề gì phần tên bạn chuyển cho nó bởi vì nó sẽ luôn ném một IllegalStateException ngay cả khi yêu cầu không chứa tên tham số này.

Ví dụ:

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(); 
} 

tôi không thể làm điều này vì nếu khách hàng gửi một tập tin mà vượt quá kích thước tối đa cuộc gọi đầu tiên để getPart sẽ ném ngoại lệ (xem getPart() Javadoc), vì vậy tôi không thể biết tôi đã nhận được tập tin nào.

Đó là lý do tại sao tôi muốn đọc các tiêu đề sắp xếp nội dung. Tôi muốn đọc tham số "param" để biết tệp nào đã ném ngoại lệ.


EDIT2: Vâng, với các API mà xuất bản 3.0 đặc điểm kỹ thuật Servlet bạn không thể kiểm soát trường hợp trước bởi vì nếu một file ném một ngoại lệ bạn không thể đọc được tên trường tập tin. Đây là một phần tiêu cực của việc sử dụng một wrapper vì rất nhiều chức năng biến mất ... Ngoài ra với FileUpload bạn có thể tự động thiết lập các chú thích MultipartConfig.

Nếu tệp vượt quá kích thước tệp tối đa, api sẽ ném ngoại lệ FileSizeLimitExceededException. Ngoại lệ cung cấp 2 phương thức để lấy tên trường và tên tệp.

Nhưng !! vấn đề của tôi vẫn chưa được giải quyết vì Tôi muốn đọc giá trị của một tham số khác được gửi cùng với tệp trong cùng một biểu mẫu. (giá trị của "param" trong ví dụ trước)


EDIT3: Tôi đang làm việc về vấn đề này. Ngay sau khi tôi viết mã, tôi sẽ xuất bản nó ở đây!

+0

Không phải là một trùng lặp. –

Trả lời

5

request.getHeader ("content-disposition") sẽ trả lại giá trị rỗng trong trường hợp của bạn, vì tiêu đề Content-Disposition xuất hiện trong nội dung HTTP POST, do đó yêu cầu chúng được xử lý riêng. Trên thực tế, Content-Disposition chỉ là tiêu đề phản hồi HTTP hợp lệ. Là một phần của yêu cầu, nó sẽ không bao giờ được coi là tiêu đề.

Bạn nên sử dụng thư viện tải lên tệp như Commons FileUpload hoặc các tính năng tải lên tệp được xây dựng của Servlet Spec 3.0 để đọc tiêu đề Content-Disposition (gián tiếp). Các thùng chứa Java EE 6 được yêu cầu để thực hiện chức năng tải lên tệp yêu cầu của Servlet Spec 3.0, thường sử dụng Tệp tải lên của Apache Commons dưới mui xe.

Nếu bạn muốn bỏ qua các thư viện đối với một số lý do chính đáng và thay vào đó đọc các tiêu đề cho mình, sau đó tôi sẽ khuyên bạn nên nhìn vào parseHeaderLinegetParsedHeaders phương thức của lớp FileUploadBase của Apache Commons FileUpload. Lưu ý rằng những phương pháp này thực sự đọc từ số InputStream được liên kết với số HttpServletRequest và bạn không thể đọc luồng hai lần. Nếu trước tiên bạn muốn đọc tiêu đề Content-Disposition trong mã của mình và sau đó sử dụng Tệp tải lên Apache Commons để phân tích cú pháp yêu cầu, bạn sẽ phải chuyển một số ServletRequestWrapper kết thúc tốt đẹp một bản sao nếu yêu cầu ban đầu đối với API tải tệp lên. Trình tự ngược lại cũng yêu cầu bạn tạo một bản sao của yêu cầu ban đầu và chuyển một bản sao ServletRequestWrapper này tới API của FileUpload. Nhìn chung, đây là thiết kế kém, vì nó không có ý nghĩa để tái tạo toàn bộ luồng trong bộ nhớ (hoặc trên đĩa) chỉ để đọc phần thân yêu cầu hai lần.

+0

Tôi đã chỉnh sửa câu hỏi với giải thích đầy đủ. –

1

Cố gắng sử dụng part.getName()

Đây là một mẫu.

tập tin 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 
    } 
} 
+0

Lưu ý: Tính năng này chỉ hoạt động đối với vùng chứa tuân thủ đặc tả Servlet 3.0 (ví dụ: không phải là phiên bản nhất định của Jetty được nhúng). –

Các vấn đề liên quan