JavaWeb Servlet文件上传下载
CoderX(远离BUG) 人气:0前言
在上网的时候我们常常遇到文件上传的情况,例如上传头像、上传资料等;当然除了上传,遇见下载的情况也很多,接下来看看我们 servlet 中怎么实现文件的上传和下载。
项目准备
idea:2020.1
jdk:1.8
tomcat:10
项目模板:java Enterprise–>Web Application
文件上传
文件上传涉及到前台页面的编写和后台服务器端代码的编写,前台发送文件,后台接收并保存文件,这才是一个完整的文件上传。
前台页面
在做文件上传的时候,会有一个上传文件的界面,首先我们需要一个表单,并且表单的请求方式为 POST;其次我们的 form 表单的 enctype 必须设为"multipart/form-data",即 enctype=“multipart/form-data”,意思是设置表单的类型为文件上传表单。默认情况下这个表单类型是 “application/x-www-form-urlencoded”, 不能用于文件上传。只有使用了multipart/form-data 才能完整地传递文件数据。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文件上传</title> </head> <body> <!--文件上传 1. 准备表单 2.设置表单提交类型为POST method="POST" 3.设置表单类型为文件上传表单 enctype="multipart/form-data" 4.设置文件提交地址 action地址需要和后台servlet注解保持一致 5.准备表单元素 6.设置表单元素的name属性值(否则后台无法接收数据) --> <form method="post" enctype="multipart/form-data" action="upLoadServlet"> 姓名:<input type="text" name="uname"><br> 文件:<input type="file" name="myfile"><br> <!--button默认时提交类型 type="submit"--> <button>提交</button> </form> </body> </html>
后台实现
使用注解 @MultipartConfig 将一个 Servlet 标识为支持文件上传。 Servlet 将 multipart/form-data 的 POST 请求封装成 Part,通过 Part 对上传的文件进行操作。
package formServlet; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.MultipartConfig; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.Part; import java.io.IOException; /* * 文件上传 * 1.使用注解@MultipartConfig,将servlet标识为支持文件上传 * 2.servlet将muitipart/form-data的POST请求封装成part对象,通过part对文件上传进行操作 * */ @WebServlet("/upLoadServlet") @MultipartConfig //文件上传注解 public class UploadServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("文件上传"); //设置请求编码格式 req.setCharacterEncoding("UTF-8"); //获取普通表单元素 String uname=req.getParameter("uname"); System.out.println("uname:"+uname); //获取part对象 Part part=req.getPart("myfile"); //通过part对象获得上传文件名 String fileName = part.getSubmittedFileName(); System.out.println("file:"+fileName); //得到文件存放路径 String filePath = req.getServletContext().getRealPath("/"); System.out.println("filePath:"+filePath); //上传文件到指定路径 part.write(filePath+"/"+fileName); } }
提交表单后查看控制台打印结果
文件上传
uname:张三
file:exception.jpg
filePath:E:\bdqn\JavaWeb\servlet\out\artifacts\servlet_war_exploded\
文件下载
文件下载,即将服务器上的资源下载(拷贝)到本地,我们可以通过两种方式下载。第一种是通过超链接本身的特性来下载;第二种是通过代码下载。
资源准备
在web目录下新建文件夹存放下载资源,通过tomcat配置添加Deployment到服务器中
超链接下载
当我们在 HTML 或 JSP 页面中使用a标签时,原意是希望能够进行跳转,但当超链接遇到浏览器不识别的资源时会自动下载;当遇见浏览器能够直接显示的资源,浏览器就会默认显示出来,比如 txt、png、jpg 等。当然我们也可以通过 download 属性规定浏览器进行下载。但有些浏览器并不支持。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文件下载</title> </head> <body> <!-- 超链接下载 1.当时用超链接(a标签)时,如果遇到浏览器能够识别的内容,会显示内容,而不会进行下载. 指定download属性进行下载; 2.如果遇到浏览器不能识别的内容,会进行下载 --> <!--浏览器能够识别的资源,显示内容--> <a href="download/1.txt">文本文件</a> <a href="download/retrun.jpg">图片文件</a> <!--压缩文件是浏览器不能识别的资源,进行下载--> <a href="download/1.zip">压缩文件</a> <!--浏览器能够识别的资源,设置download属性,进行下载--> <!--download="文件名.后缀名",不设置文件名和后缀名会默认服务器中的文件属性--> <a href="download/1.txt" download>文本文件下载</a> <a href="download/retrun.jpg" download="re.png">图片文件下载</a> </body> </html>
download 属性可以不写任何信息,会自动使用默认文件名。如果设置了download属性的值,则使用设置的值做为文件名。当用户打开浏览器点击链接的时候就会直接下载文件。
后台实现下载
实现步骤
- 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 “application/octet-stream” 或 “application/x-msdownload” 等。
- 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 为 “attachment;filename=文件名”
- 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。
package formServlet; import jakarta.servlet.ServletException; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.IOException; /** * 文件下载 * 1. 需要通过 response.setContentType 方法设置 Content-type 头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 "application/octet-stream" 或 "application/x-msdownload" 等。 * 2. 需要通过 response.setHeader 方法设置 Content-Disposition 头的值 为 "attachment;filename=文件名" * 3. 读取下载文件,调用 response.getOutputStream 方法向客户端写入附件内容。 */ @WebServlet("/downloadServlet") public class DownloadServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("文件下载..."); //设置请求编码格式 req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); //获取参数(下载文件名) String fileName = req.getParameter("fileName"); System.out.println(fileName); //参数非空判断 trim():去除字符串的前后空格 if(fileName==null||"".equals(fileName.trim())){ //参数为空,写入浏览器提示 resp.getWriter().write("请输入要下载的文件名!"); resp.getWriter().close(); //关闭流 return; //退出当前 } //得到文件存放路径 String filePath=req.getServletContext().getRealPath("/download/"); //通过路径得到file对象 File file = new File(filePath + fileName); //判断文件对象是否存在并且是标准文件 if(file.exists()&&file.isFile()){ //设置响应类型(浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型) resp.setContentType("application/x-msdownload"); //设置响应头 resp.setHeader("Context-Disposition","attachment;filename="+fileName); //得到file文件输入流 FileInputStream fis = new FileInputStream(file); //得到字节输出流 ServletOutputStream sos=resp.getOutputStream(); //定义byte数组 byte[] bytes=new byte[1024]; //定义长度 int len=fis.read(bytes); //循环输出 while (len!=-1){ sos.write(bytes,0,len); } //关闭资源 先打开的后关闭 sos.close(); fis.close(); }else { resp.getWriter().write("文件不存在,请重试!"); resp.getWriter().close(); } } }
总结
加载全部内容