跟著書上的例子寫了個文件上傳的簡單頁面,感覺還蠻有意思的
前端
要上傳文件,必須利用multipart/form-data設(shè)置HTML表單的enctype屬性。
<form action="action" method="post" enctype="multipart/form-data">
Select a file <input type="file" name="fieldName" /> 這個fieldName必須設(shè)置
服務(wù)器端
通過MultipartConfig注解類型和javax.servlet.http.Part接口進(jìn)行處理,處理上傳文件的Servlet必須用@MultipartConfig進(jìn)行標(biāo)注
MultipartConfig有以下可選屬性
- maxFileSize,表示最多可上傳的文件容量,默認(rèn)值-1。
- maxRequestSize,表示允許多部分HTTP請求的最大容量,默認(rèn)值為-1
- location,指定上傳的文件保存到磁盤中的指定位置
- fileSizeThreshold,設(shè)定一個溢出尺寸,超過這個值的文件將被臨時存儲在磁盤
HttpServletRequest 接口定義了以下方法來處理多部分的請求
- Part getPart(String name),返回與指定名稱相關(guān)的Part,這個name與前端頁面中input的name相同。
- Collection<Part> getParts(),返回所有Part
- String getContentType(),如果Part是一個文件,返回Part的內(nèi)容類型,否則返回null
- Collection<String> getHeaderNames(),返回這個Part中的所有header名稱
- void write(String path),將文件寫入指定的路徑
- void delete(),刪除該文件對應(yīng)的存儲,包括相關(guān)的臨時文件
- InputStream getInputStream(),以流形式返回上傳文件的內(nèi)容
域的形式
如果上傳域中有一個名為document的note.txt文件時,產(chǎn)生的header
content-type:text/plain
content-disposition:form-data; name="document"; filename="note.txt"
如果是一個非文件的域,Part將只有content-disposition的header
格式:content-disposition:form-data; name="fiedlName"
范例
@WebServlet(urlPatterns = "/singleUpload")
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 3, maxFileSize = 1024 * 1024 * 10)
public class UploadFileServlet extends HttpServlet {
private static final long serialVersionUID = 8593039L;
/**
* 從Part中提取文件名
* @param part
* @return
*/
private String getFileName(Part part) {
String contentDispositionHeader = part.getHeader("content-disposition");
String[] elements = contentDispositionHeader.split(";");
for (String element : elements) {
if (element.trim().startsWith("filename")) {
return element.substring(element.indexOf('=') + 1).trim().replace("\"", "");
}
}
return null;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Part part = req.getPart("filename");
String filename = getFileName(part);
if (filename != null && !filename.isEmpty()) { //檢測文件名是否合法
// 在WEB-INF目錄下創(chuàng)建/tmp/upload/文件夾,將上傳文件存儲到這個文件夾下
// WEB-INF目錄下的文件是無法通過鏈接直接訪問的
File f = new File(getServletContext().getRealPath("/WEB-INF") + "/tmp/upload/");
if (!f.exists()) {
f.mkdirs();
}
// 將文件寫入
part.write(getServletContext().getRealPath("/WEB-INF") + "/tmp/upload/" + filename);
}
// 返回文件的名字,大小,上傳者等信息
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.print("<br/>Upload file name: " + filename);
writer.print("<br/>Size: " + part.getSize());
String author = req.getParameter("author");
writer.print("<br/>Author: " + author);
writer.close();
}
}
再來看下前端頁面singleUpload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Select a file to upload</h1>
<form action="singleUpload" enctype="multipart/form-data", method="post">
Author: <input type="text" name="author" /><br/>
<!-- 這里name的值“filename”在獲取Part對象時使用 -->
Select file to upload <input type="file" name="filename" /> <br/>
<input type="submit" value="Upload">
</form>
</body>
</html>

頁面
點擊上傳就可以在配置的文件夾下看到自己上傳的文件了。
總結(jié)
這篇博客只是實現(xiàn)了一個很簡單的文件上傳,算是給自己的后端之路挖下第一個坑(???)一直感覺后端很高大上,第一次動手寫東西果然高大上hhhhh,Android里沒怎么使用到的注解啊,文件,IO流都在這里得到了較多使用,很神奇的感覺(手動捂臉)。希望能慢慢學(xué)點后端知識吧。