上傳支持
一、Servlet3.0 新特性 概述
Servlet3.0的主要新特性如下三部分:
- 使用
@WebServlet
、@WebFilter
、@WebListener
三個註解來替代web.xml文件中的Servlet、Filter、Listener的配置; - Servlet異步處理:當Servlet處理比較費時的問題時,這會讓客戶感覺到很卡。當使用異常處理時可以把已經處理好的內容先一步響應給客戶端瀏覽器,然後使用另一個線程來完成費時的操作,也就是把內容一部分一部分的顯示出來;
- 上傳組件:不用再使用fileupload等第三方的上傳組件,使用Servlet3.0的上傳組件會更方便。
這篇文章我們介紹一下servlet3.0中對上傳的支持。
二、回憶一下以前的上傳
我們先回憶一下,以前的上傳是怎麼做的。
首先是對錶單的要求:
- 表單的method必須是post,即
method="POST"
- 其次enctype屬性爲multipart/form-data,也就是
enctype="multipart/form-data"
- 而且一定要給出一個上傳文件的表單項項
<input type="file" name="xxx"/>
然後是在servlet的使用上, request.getParameter()方法不能再使用,必須使用request.getInputStream()
來獲取整個表單的數據。
而且我們還要使用 commons-fileupload
組件,創建工廠,創建解析器,使用解析器來解析request對象,得到List<FileStream>。
三、Servlet3.0 的上傳
在servlet3.0中,我們使用上傳的時候,表單的要求是不變的,還是需要上面說的那幾項,可是我們在servlet中,就不必再使用commons-fileupload,而是使用Servlet3.0提供的上傳組件接口。
接下來我們介紹一下上傳的步驟:
1. 上傳表單
爲了演示,我們先創建一個上傳的表單:
<form action="<c:url value='/AServlet'/>" method="post" enctype="multipart/form-data">
用戶:<input type="text" name="username" /><br>
簡歷:<input type="file" name="resume" /><br>
<input type="submit" value="註冊" />
</form>
表單中只有兩個表單項,一個是用戶名,username
。另一個是文件表單項,resume
。請求的URL爲/AServlet
。
2. Servlet添加註解
要注意的一點是,默認Servlet是不支持使用上傳組件:需要給Servlet添加一個註解: @MultipartConfig
也就是:
@MultipartConfig
public class AServlet extends HttpServlet {
...
...
}
3. 獲取username
在servlet3.0中,request.getParameter()方法又可以重新使用了。
我們可以獲取username字段的值。
也就是:
String username = request.getParameter("username");
4. 獲取文件表單項
我們想要獲得文件表單項的字段。應該使用getPart()
方法。
我們首先要使用request.getPart("字段名")
方法,得到對應的Part對象。
Part part = request.getPart("resume");
Part對象有幾個重要的方法:
String getContentType()
:獲取上傳文件的MIME類型StringgetName()
:獲取表單項的名稱,不是文件名稱String getHeader(String header)
:獲取指定頭的值long getSize()
:獲取上傳文件的大小InputStream getInputStream()
:獲取上傳文件的內容void write(String fileName)
:把上傳文件保存到指定路徑下
我們上面既然已經得到了Part對象,接下來利用它的方法,獲取我們想要的信息就可以了。
例如:
// 獲取上傳文件的MIME類型
String contentType = part.getContentType();
System.out.println(contentType);
// 獲取上傳文件的字節數
long size = part.getSize();
System.out.println(size);
// 獲取文件字段的名稱
String name = part.getName();
System.out.println(name);
// 獲取頭信息,這個頭中包含了上傳文件的名稱
String header = part.getHeader("Content-Disposition");
System.out.println(header);
// 保存文件
part.write("C:/XXX.jpg");
5. 上傳文件名
有一點比較遺憾的是,他沒有提供獲取上傳文件名的方法。這裏呢,需要我們自己來完成對文件名的截取操作。
就從上面我們獲取的Content-Disposition中截取出來即可。
// 截取文件名稱
String header = part.getHeader("Content-Disposition");
int start = header.lastIndexOf("filename=\"") + 10;
int end = header.length() - 1;
String filename = header.substring(start, end);
System.out.println(filename);
END.