跟著書(shū)上的例子寫(xiě)了個(gè)文件上傳的簡(jiǎn)單頁(yè)面狂丝,感覺(jué)還蠻有意思的
前端
要上傳文件救斑,必須利用multipart/form-data設(shè)置HTML表單的enctype屬性。
<form action="action" method="post" enctype="multipart/form-data">
Select a file <input type="file" name="fieldName" /> 這個(gè)fieldName必須設(shè)置
服務(wù)器端
通過(guò)MultipartConfig注解類型和javax.servlet.http.Part接口進(jìn)行處理真屯,處理上傳文件的Servlet必須用@MultipartConfig進(jìn)行標(biāo)注
MultipartConfig有以下可選屬性
- maxFileSize脸候,表示最多可上傳的文件容量,默認(rèn)值-1绑蔫。
- maxRequestSize运沦,表示允許多部分HTTP請(qǐng)求的最大容量,默認(rèn)值為-1
- location配深,指定上傳的文件保存到磁盤(pán)中的指定位置
- fileSizeThreshold携添,設(shè)定一個(gè)溢出尺寸,超過(guò)這個(gè)值的文件將被臨時(shí)存儲(chǔ)在磁盤(pán)
HttpServletRequest 接口定義了以下方法來(lái)處理多部分的請(qǐng)求
- Part getPart(String name)篓叶,返回與指定名稱相關(guān)的Part烈掠,這個(gè)name與前端頁(yè)面中input的name相同。
- Collection<Part> getParts()缸托,返回所有Part
- String getContentType()左敌,如果Part是一個(gè)文件,返回Part的內(nèi)容類型俐镐,否則返回null
- Collection<String> getHeaderNames()矫限,返回這個(gè)Part中的所有header名稱
- void write(String path),將文件寫(xiě)入指定的路徑
- void delete()佩抹,刪除該文件對(duì)應(yīng)的存儲(chǔ)叼风,包括相關(guān)的臨時(shí)文件
- InputStream getInputStream(),以流形式返回上傳文件的內(nèi)容
域的形式
如果上傳域中有一個(gè)名為document的note.txt文件時(shí)棍苹,產(chǎn)生的header
content-type:text/plain
content-disposition:form-data; name="document"; filename="note.txt"
如果是一個(gè)非文件的域无宿,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()) { //檢測(cè)文件名是否合法
// 在WEB-INF目錄下創(chuàng)建/tmp/upload/文件夾,將上傳文件存儲(chǔ)到這個(gè)文件夾下
// WEB-INF目錄下的文件是無(wú)法通過(guò)鏈接直接訪問(wèn)的
File f = new File(getServletContext().getRealPath("/WEB-INF") + "/tmp/upload/");
if (!f.exists()) {
f.mkdirs();
}
// 將文件寫(xiě)入
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();
}
}
再來(lái)看下前端頁(yè)面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對(duì)象時(shí)使用 -->
Select file to upload <input type="file" name="filename" /> <br/>
<input type="submit" value="Upload">
</form>
</body>
</html>
點(diǎn)擊上傳就可以在配置的文件夾下看到自己上傳的文件了。
總結(jié)
這篇博客只是實(shí)現(xiàn)了一個(gè)很簡(jiǎn)單的文件上傳坡垫,算是給自己的后端之路挖下第一個(gè)坑(???)一直感覺(jué)后端很高大上梭灿,第一次動(dòng)手寫(xiě)東西果然高大上hhhhh,Android里沒(méi)怎么使用到的注解啊冰悠,文件堡妒,IO流都在這里得到了較多使用,很神奇的感覺(jué)(手動(dòng)捂臉)溉卓。希望能慢慢學(xué)點(diǎn)后端知識(shí)吧皮迟。