文件上传与下载
一、文件上传
- 要有一个 form 标签,method=post 请求
- form 标签的 encType 属性值必须为 multipart/form-data 值
- 在 form 标签中使用 input type=file 添加上传的文件
- 编写服务器代码(Servlet 程序)接收,处理上传的数据。
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器

导入jar包处理文件和对象

commons-fileupload.jar 常用 API 介绍说明
ServletFileUpload 类,用于解析上传的数据。
FileItem 类,表示每一个表单项。
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request); 判断当前上传的数据格式是否是多段的格式。
public List parseRequest(HttpServletRequest request) 解析上传的数据
boolean FileItem.isFormField() 判断当前这个表单项,是否是普通的表单项。还是上传的文件类型。
- true 表示普通类型的表单项
- false 表示上传的文件类型
String FileItem.getFieldName() 获取表单项的 name 属性值
String FileItem.getName(); 获取上传的文件名
void FileItem.write( file ); 将上传的文件写到 参数 file 所指向抽硬盘位置 。
上传文件的表单:
1 2 3 4 5
| <form action="http://192.168.31.74:8080/09_EL_JSTL/uploadServlet" method="post" enctype="multipart/form-data"> 用户名:<input type="text" name="username" /> <br> 头像:<input type="file" name="photo" > <br> <input type="submit" value="上传"> </form>
|
解析上传的数据的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException { if (ServletFileUpload.isMultipartContent(req)) { FileItemFactory fileItemFactory = new DiskFileItemFactory(); ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory); try { List<FileItem> list = servletFileUpload.parseRequest(req); for (FileItem fileItem : list) { if (fileItem.isFormField()) { System.out.println("表单项的 name 属性值:" + fileItem.getFieldName()); System.out.println("表单项的 value 属性值:" + fileItem.getString("UTF-8")); } else { System.out.println("表单项的 name 属性值:" + fileItem.getFieldName()); System.out.println("上传的文件名:" + fileItem.getName()); fileItem.write(new File("e:\\" + fileItem.getName())); } } } catch (Exception e) { e.printStackTrace(); } } }
|
二、文件下载
下载的常用 API 说明:
response.getOutputStream();
servletContext.getResourceAsStream();
servletContext.getMimeType(); :获取要下载的文件类型
response.setContentType(); :在回传前,通过响应头告诉客户端返回的数据类型
response.setHeader(“Content-Disposition”, “attachment; fileName=1.jpg”);
这个响应头告诉浏览器。这是需要下载的。而 attachment 表示附件,也就是下载的一个文件。fileName=后面,表示下载的文件名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class Download extends HttpServlet {
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String downloadFileName = "2.jpg";
ServletContext servletContext = getServletContext(); String mimeType = servletContext.getMimeType("/file/" + downloadFileName); System.out.println("下载的文件类型:" + mimeType);
resp.setContentType(mimeType);
if (req.getHeader("User-Agent").contains("Firefox")) { resp.setHeader("Content-Disposition", "attachment; filename==?UTF-8?B?" + new BASE64Encoder().encode("中国.jpg".getBytes("UTF-8")) + "?="); } else { resp.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("中国.jpg", "UTF-8")); }
InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName); OutputStream outputStream = resp.getOutputStream(); IOUtils.copy(resourceAsStream, outputStream); } }
|
解决中文乱码问题
法一:URLEncoder 解决 IE 和谷歌浏览器的 附件中文名问题
1 2 3 4
| String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");
response.setHeader("Content-Disposition", str);
|
法二:BASE64编解码 解决 火狐浏览器的附件中文名问题
1 2 3 4 5
| String str = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";
response.setHeader("Content-Disposition", str);
|