上傳文件
Servlet的參數設置
採用annotation方式以下:java
- @WebServlet(
- name = "TicketServlet",
- urlPatterns = {"/tickets"},
- loadOnStartup = 1
- )
- /* MultipartConfig配置了本Servlet的文件上傳參數,
- * location:這裏沒有列出的是location參數,表示存放臨時文件的位置,通常無需配置,選擇缺省的臨時文件夾
- * fileSizeThreshold:表示收到文件到達這麼大後,不在放入緩存,而是寫入臨時文件。本例中,若是文件小於5M,則存放在緩存,而後被垃圾回收;一樣的,若是採用臨時文件方式,臨時文件也會被刪除。
- * maxFileSize:限制文件的最大值,本例文件不超過20M
- * maxRequestSize:因爲可能同時上傳多個文件,servlet可能會被同時請求,此限制總量。
- */
- @MultipartConfig(
- fileSizeThreshold = 5_242_880, // 5M
- maxFileSize = 20_971_520L, //20M
- maxRequestSize = 41_943_040L //40M
- )
採用web.xml的方式以下:web
- <servlet>
- <multipart-config>
- <location>......</location>
- <file-size-threshold>......</file-size-threshold>
- <max-file-size>......</<max-file-size>
- <max-request-size>......</max-request-size>
- </multipart-config>
- </servlet>
Multipart上傳文件
下面是Create Ticket的HTML,文件上傳有關的是<form… enctype="multipart/form-data"/>和<input type="file" name="file1"/>緩存
- <!DOCTYPE html>
- <html>
- <head>
- <title>Customer Support</title>
- </head>
- <body>
- <h2>Create a Ticket</h2>
- <form method="POST" action="tickets" enctype="multipart/form-data">
- <input type="hidden" name="action" value="create"/>
- Your Name<br/>
- <input type="text" name="customerName"/><br/><br/>
- Subject<br/>
- <input type="text" name="subject"/><br/><br/>
- Body<br/>
- <textarea name="body" rows="5" cols="30"></textarea><br/><br/>
- <b>Attachments</b><br/>
- <input type="file" name="file1"/><br/><br/>
- <input type="submit" value="Submit"/>
- </form>
- </body>
- </html>
點擊submite,將觸發一個action=create的POST請求,抓包以下:app
- POST /customer-support/tickets HTTP/1.1
- Host: 191.8.1.103:8080
- User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0
- Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
- Accept-Language: en-US,en;q=0.5
- Accept-Encoding: gzip, deflate
- Referer: http://191.8.1.103:8080/customer-support/tickets?action=create
- Connection: keep-alive
- Content-Type: multipart/form-data; boundary=---------------------------168557226814076645131805352216
- Content-Length: 729
-
- -----------------------------168557226814076645131805352216
- Content-Disposition: form-data; name="action"
-
- create
- -----------------------------168557226814076645131805352216
- Content-Disposition: form-data; name="customerName"
-
- Wei
- -----------------------------168557226814076645131805352216
- Content-Disposition: form-data; name="subject"
-
- moon
- -----------------------------168557226814076645131805352216
- Content-Disposition: form-data; name="body"
-
- Hello,world
- -----------------------------168557226814076645131805352216
- Content-Disposition: form-data; name="file1"; filename="moon.txt"
- Content-Type: text/plain
-
- Hello, Moon!
- Hello, my friend!
-
- -----------------------------168557226814076645131805352216--
先對比普通的form-data的HTTP POST消息體的例子以下。和GET的參數傳遞部分是同樣的。ide
action=create&customerName=j&subject=jj&body=jjjjurl
如今,咱們在HTML中指明enctype="multipart/form-data",所以在HTTP POST的封裝中採用了multipart/form-data的方式。這在RFC1867 Form-based File Uploadin HTML中有詳細的規定,包括file類型。對於普通的form-data的內容讀取有下面兩個方式:orm
(1)經過javax.servlet.http.part類來讀取xml
- Part part1 = request.getPart("customerName");
- System.out.println(part1.getHeader("Content-Disposition"));
- InputStream is = part1.getInputStream();
- int len = is.available();
- byte[] buff = new byte[len];
- is.read(buff);
- System.out.println(new String(buff));
(2)提供了更直接的方式htm
- System.<em>out</em>.println(<strong>request.getParameter("customerName"));</strong>
毫無疑問,咱們會採用第二種方式,可是第一種方式提供了通用的讀取multipart的方法。咱們將使用該方式讀取上傳文件部分,小例子的代碼以下:
- private void createTicket(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
- //獲取普通的form-data信息
- String customerName = request.getParameter("customerName");
- String subject = request.getParameter("subject");
- String body = request.getParameter("body");
-
- //讀取上傳文件部分:獲取相應的multipart
- Part filePart = request.getPart("file1");
- //讀取上傳文件部分:getSize()是multipart中信息的大小,而非整個multipart的大小,對應即爲上傳文件的大小
- if(filePart != null && filePart.getSize() > 0){
- // 獲取文件名稱,即Content-Disposition: form-data; name="file1"; filename="moon.txt"中的filename,咱們能夠經過filePart.getHeader("Content-Disposition")分析獲取。javax.servlet.http.Part直接提供了方法
- String fileName = filePart.getSubmittedFileName();
- // 獲取文件上傳內容放。
- InputStream inputStream = filePart.getInputStream();
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- int read;
- final byte[] bytes = new byte[1024];
- while((read = inputStream.read(bytes)) != -1){
- outputStream.write(bytes, 0, read);
- }
- /* 若是是二進制,經過outputStream.toByteArray()得到byte[]。任何格式均適合二進制;若是是文本文件,能夠先經過filePart.getHeader("Content-Type")來確認,直接outputStream.toString() */
- … …
- }
- ......
- }