文件的上传与下载
文件上传
-
步骤
-
要有一个form标签,method=post请求
-
form标签中的encType属性必须为multipart/form-data
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼 接,然后以二进制流的形式发送给服务器
-
在form标签中使用input type =file添加上传文件
-
编写服务器代码(servlet程序)接收,处理上传的数据
-
-
commons-fileupload.jar的常用 API
要想实现文件上传,我们需要导入以下两个jar包
- ServletFileUpload :用于解析上传的数据
- FileItem :表示每一个表单项
- ServletFileUpload.isMultipartContent(HttpServletRequest request):判断上传的数据格式是否以多段形式上传
- List parseRequest(HttpServletRequest request):解析上传的数据
- FileItem.isFormField():判断当前表单项是否为普通的表单项,true代表普通类型,false代表文件类型
- FileItem.getFieldName():获取当前表单项的属性值
- FileItem.getString():获取当前表单项的值
- FileItem.getName():获取上传的文件名
- FileItem.write(File file):将上传的文件写道参数file所指向的硬盘位置
-
使用以上方法,实现文件的上传
servlet程序
public class UploadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.ServletFileUpload.isMultipartContent(req):判断上传的数据格式是否是多段的 if(ServletFileUpload.isMultipartContent(req)){ //2.创建FileItemFactory工厂的实现类 FileItemFactory fileItemFactory = new DiskFileItemFactory(); //3.创建用于解析的工具类ServletFileUpload ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory); try { //4.解析上传的数据 List<FileItem> list = servletFileUpload.parseRequest(req); //5.遍历上传的数据 for(FileItem item : list){ //6.判断上传的是否为普通的表单项,true代表是普通表单,false代表是文件 if(item.isFormField()){ System.out.println("表单项的name属性值为:" + item.getFieldName()); System.out.println("表单项的value属性值为:" + item.getString()); }else { System.out.println("表单项的name属性值为:" + item.getFieldName()); System.out.println("上传的文件名为:" + item.getName()); //7.将文件保存到硬盘 item.write(new File("d:\\" + item.getName())); } } } catch (Exception e) { e.printStackTrace(); } } } }
JSP页面
<body> <form action="http://localhost:8080/FileUploadAndDownload/uploadServlet" method="post" enctype="multipart/form-data"> 用户名:<input type="text" name="username" /><br/> <input type="file" name="fileImg" /><br> <input type="submit" value="提交"> </form> </body>
文件下载
-
步骤
- 获取需要下载的文件名
- 读取下载的文件信息(使用ServletContext)
- 在回传前,通过响应头告诉客户端返回的数据类型
- 通过响应头告诉浏览器返回的数据适用于下载使用
- 把下载的文件内容回传到浏览器
-
按照以上步骤,实现文件下载
public class DownloadServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.获取下载的文件名 String downloadFilename = "a.jpg"; //2.读取文件信息(ServletContext) ServletContext servletContext = getServletContext(); //获取文件的下载类型 String mimeType = servletContext.getMimeType("/imgs/" + downloadFilename); System.out.println("下载的类型为:" + mimeType); //3.在回传前,通过响应头告诉客户端返回的数据类型 resp.setContentType(mimeType); //4.通过响应头告诉浏览器返回的数据适用于下载使用 //resp.setHeader("Content-Disposition", "attachment; filename=中国.jpg"); 这样会产生乱码的问题 //使用URLEncoder类对中文名进行UTF-8形式的编码(适用于IE或谷歌浏览器) //resp.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("中国.jpg","utf-8")); //判断浏览器是否为火狐浏览器 if(req.getHeader("User-Agent").contains("Firefox")){ String str = "attachment; filename=" + "=?utf-8?B?" + new BASE64Encoder().encode(downloadFilename.getBytes("utf-8")) + "?="; resp.setHeader("Content-Disposition", str); }else { String str = "attachment; filename=" + URLEncoder.encode(downloadFilename,"utf-8"); resp.setHeader("Content-Disposition", str); } //5.把下载的文件内容回传到浏览器 InputStream resourceAsStream = servletContext.getResourceAsStream("/imgs/" + downloadFilename); OutputStream outputStream = resp.getOutputStream(); //将读取到的文件信息,复制到输出流,传给浏览器 IOUtils.copy(resourceAsStream,outputStream); } }
-
解决保存中文文件名出现乱码的问题
使用URLEncoder类对中文名进行UTF-8形式的编码(适用于IE或谷歌浏览器)
String str = "attachment; filename=" + URLEncoder.encode(downloadFilename,"utf-8");
火狐浏览器需要使用Base64进行编码(filename==?charset?B?xxxxx?=)
- =? 表示 要开始进行编码了
- charset 表示 编码的字符集
- B 表示 使用Base64进行编码
- xxxxx 表示 编码后的内容
- ?= 表示 编码的结束
使用Base64进行编码解码操作
@Test public void test() throws Exception { String str = "这是需要转化的Base64的信息"; //创建一个Base64编码器 BASE64Encoder base64Encoder = new BASE64Encoder(); String encode = base64Encoder.encode(str.getBytes("utf-8")); System.out.println(encode); //6L+Z5piv6ZyA6KaB6L2s5YyW55qEQmFzZTY055qE5L+h5oGv //如何解码操作 //创建解码器 BASE64Decoder base64Decoder = new BASE64Decoder(); byte[] bytes = base64Decoder.decodeBuffer(encode); String str2 = new String(bytes,"utf-8"); System.out.println(str2); }