一、文件上传代码实现
代码实现很简单:
主要是用到了客户端 HTML 页面的表单元素,使用<form>
标签的 enctype
属性,并设置它的值为 multipart/formdata
,意思是:多部分/表单数据
,同时使用<input type="file">
的输入域用于指定上传的文件。
关于form
表单 enctype
属性:
值 | 描述 |
---|---|
application/x-www-form-urlencoded | 在发送前编码所有字符(默认) |
multipart/form-data | 不对字符编码,每一个表单项分割为一个部件 |
text/plain | 空格转换为加号,但不对特殊字符编码 |
这是前端代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传</title>
</head>
<body>
${message}<br>
<form action="fileUpload" method="post" enctype="multipart/form-data">
<table>
<tr>
<td align="center" colspan="2">文件上传</td>
</tr>
<tr>
<td>用户名: </td>
<td><input type="text" name="username" size="30"></td>
</tr>
<tr>
<td>文件: </td>
<td><input type="file" name="filename" size="30"></td>
</tr>
<tr>
<td><input type="submit" value="提交"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
</body>
</html>
这是后台的接口:
@WebServlet(name = "FileUploadServlet", urlPatterns = "/fileUpload")
@MultipartConfig(location = "D:\\", fileSizeThreshold = 1024)
public class FileUploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = this.getServletContext().getRealPath("/");//返回web应用程序文档根目录
String username = request.getParameter("username");
Part part = request.getPart("filename");
String message = "";
if (part.getSize() > 1024 * 1024) {
part.delete();
message = "文件大小不能超过1MB";
} else {
path += "\\user\\" + username;
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
String h = part.getHeader("Content-Disposition");
String fname = getFileName(h);
part.write(path + "\\" + fname);
message = "文件上传成功";
}
request.setAttribute("message", message);
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
/** * 根据请求头解析出文件名 * 请求头的格式:火狐和google浏览器下:form-data; name="file"; filename="snmp4j--api.zip" * IE浏览器下:form-data; name="file"; filename="D:\snmp4j--api.zip" * @param header 请求头 * @return 文件名 */
public String getFileName(String header) {
/** * String[] tempArr1 = header.split(";"); * 代码执行完之后,在不同的浏览器下,tempArr1数组里面的内容稍有区别: * 火狐或者google浏览器下:tempArr1={form-data,name="file",filename="snmp4j--api.zip"} * IE浏览器下:tempArr1={form-data,name="file",filename="D:\snmp4j--api.zip"} */
String[] tempArr1 = header.split(";");
/** *火狐或者google浏览器下:tempArr2={filename,"snmp4j--api.zip"} *IE浏览器下:tempArr2={filename,"D:\snmp4j--api.zip"} */
String[] tempArr2 = tempArr1[2].split("=");
//获取文件名,兼容各种浏览器的写法
String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\")+1).replaceAll("\"", "");
return fileName;
}
}
假如上传了一张图图片:
那么请求头信息为:
二、原理分析
当表单提交的时候,浏览器将表单的各部分发送到服务器端,在服务器端使用 part
的 write()
方法可以将文件保存在服务器的特定位置。
Part
接口为 Servlet3.0 新增的接口,在servlet.http
包下,它表示多部分表单的一个部分。
- public String
getHeader
(String name):返回Part
对象指定的MIME
头的值。 - public long
getSize
():返回Part
对象的大小。 - public void
write
(String path):将Part
对象写入到指定的位置。
必须使用@MultipartConfig
注解:
- 该注解告诉容器该 Servlet 能够处理
multipart/formdata
的请求。 - 使用该注解
request
对象才可以得到表单的各部分
。
常用的注解元素为:
也可以使用配置文件的方式进行配置,元素值与标签相同。
三、文件下载
/** * 文件下载 servlet */
@WebServlet(urlPatterns = "/downloadServlet")
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1、文件存放路径
String path = "D:/fileUpload/";
// 2、需要下载的文件名
String fileName = "test.jpg";
File file = new File(path + fileName);
response.reset();
response.setCharacterEncoding("UTF-8");
fileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
InputStream input = new FileInputStream(file);
ServletOutputStream out = response.getOutputStream();
byte[] buff = new byte[1024];
int len;
while ((len = input.read(buff)) != -1) {
out.write(buff, 0, len);
out.flush();
}
input.close();
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
在D:\fileUpload\test.jpg
要有图片,才可以完成下载。