在 Web 开发中,经常遇到的一种场景就是将文件上传到服务器。比如,在需要客户信息时上传的头像;上传文件到网盘中;上传附件到邮箱等。这些都要用到文件上传的知识,那么上传文件是怎么实现的呢?
- web 端
<form action="/upload" method="post" enctype="multipart/form-data">
上传人:<input type="text" name="name"><br/>
请选择文件:<input type="file" name="filename"><br/>
<input type="submit" value="上传">
</form>
文件上传通过 form 表单实现,设置 enctype 属性为 multipart/form-data 。
- servlet 服务端解析文件
public class Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String file = request.getParameter("filename");
String name = request.getParameter("name");
System.out.println(file);
System.out.println(name);
DiskFileItemFactory factory = new DiskFileItemFactory();
//缓存文件位置
factory.setRepository(new File(getServletContext().getRealPath("/temp")));
//1M 临时缓冲区大小
factory.setSizeThreshold(1024*1024);
//拿到解析器对象
ServletFileUpload parser = new ServletFileUpload(factory);
parser.setHeaderEncoding("utf-8");
try {
java.util.List<FileItem> list = parser.parseRequest(request);
for (FileItem fileItem:list){
if (fileItem.isFormField()){
//普通
String fieldName = fileItem.getFieldName();
String value = fileItem.getString("utf-8");
System.out.print(fieldName + " = " + value);
}else {
//文件上传
String filename = fileItem.getFieldName();
String savePath = getServletContext().getRealPath("WEB-INF/upload");
InputStream in = fileItem.getInputStream();
OutputStream out = new FileOutputStream(new File(savePath, filename));
byte[] buf = new byte[1024];
int len = 0;
while ((len=in.read(buf))>0){
out.write(buf, 0 , len);
}
in.close();
out.close();
//删除缓存文件;
fileItem.delete();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
服务端解析上传文件,通过 DiskFileItemFactory 类来实现。每一个上传的文件解析成一个单独的 FileItem 。通过操作 FileItem 可以对上传的文件进行读取、转存等操纵。
ps: 需要依赖 jar 包 commons-io-1.4.jar 和 commons-fileupload-1.2.2.jar 。
在 Servlet 端通过 Request 可以设置上传文件的大小、类型,保证上传文件的正确性;可以设置文件存放位置,防止外界的访问;修改文件名,保证文件的唯一性等。通过 ServletFileUpload 还可以监听上传文件进度,进而让用户及时知道上传情况。这些都是对 Servlet 端的完善操作,更多知识需要小伙伴们去探索。