Javaweb之实现文件上传+点击下载功能
Javaweb之实现文件上传+点击下载功能
实现目标:
1、编写index.jsp,可以进行文件上传
2、上传成功后跳回index.jsp,并把上传的文件名显示在index.jsp中(用a标签显示)。
3、点击文件名,可下载文件
准备工具:
IntelliJ IDEA 2019.2.3 x64
apache-tomcat-8.5.15
JSP 标准标签库(JSTL)
首先,简单编写Index,jsp的上传页面
<%-- Created by IntelliJ IDEA. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>upload && download</title> </head> <body> //enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。 //不对字符编码。在使用包含文件上传控件的表单时,必须使用该值 <form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="上传"> </form> </body> </html>
再来编写UploadServlet.java的实现上传的IO
package com.blb.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.*; import java.nio.file.Path; //支持二进制处理 @MultipartConfig @WebServlet("/upload") //映射路径 public class UploadServlet extends HttpServlet { String path="d:/upload/"; //上传的路径 这里我设置的是d盘的upload文件夹下 @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Part file = req.getPart("file"); //获取提交的文件名 String fileName = file.getSubmittedFileName(); //获取文件的输入流 InputStream inputStream = file.getInputStream(); //获取的文件传到path路径 FileOutputStream fileOutputStream = new FileOutputStream(path+fileName); byte[] data = new byte[1024]; int len; while ((len=inputStream.read(data))!=-1){ // 表示从InputStream中读取一个数组的数据,如果返回-1 则表示数据读取完成了。 fileOutputStream.write(data,0,len); //循环读取数据 } inputStream.close(); fileOutputStream.close(); //关闭IO流 } }
检查一下,没什么错误,试着看看效果
选择一个图片文件
点击上传后
检查D:/upload下是否有这个文件
证明咱们这个逻辑没问题哈,已经能实现上传到指定路径了
接着实现上传成功后跳回index.jsp,并把上传的文件名显示在index.jsp中(用a标签显示)。
这里先导入一个jstl的jsp
一定要在WEB-INF下导入,然后右键jstl选择 as a libray
导入完成后在jsp头部加入一个引入标签,然后在主体里加入forEach遍历这个上传的文件list 显示在浏览器的页面上
<%-- Created by IntelliJ IDEA. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> //jstl引入标签 <html> <head> <title></title> </head> <body> <form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="上传"> </form> <h1>文件列表</h1> <c:forEach items="${files}" var="file"> <a href="download?file=${file}">${file}</a><br> //上传文件的名字的显示在a标签内 </c:forEach> </body> </html>
接着写实现点击a标签下载上传后的文件的功能代码DownloadServlet.java
package com.blb.servlet; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.ws.Service; import java.io.FileInputStream; import java.io.IOException; @MultipartConfig @WebServlet("/download") public class DownloadServlet extends HttpServlet { String path="D:/"; @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //要下载的文件名 String file = req.getParameter("file"); //取得文件输入流 FileInputStream fileInputStream = new FileInputStream(path + file); //获得输出流 ServletOutputStream outputStream = resp.getOutputStream(); //将文件名转码 String fileName = new String(file.getBytes(), "iso-8859-1"); resp.setContentType("application/octet-stream"); //告诉浏览器我这是一个二进制文件 resp.setHeader("Content-Disposition", "attachment;filename=" + fileName); //告诉浏览器文件名是什么 resp.setContentLength(fileInputStream.available()); //告诉浏览器文件的大小是多少 //IO流写操作,向客户端写内容 byte[] data = new byte[1024]; int len; while ((len=fileInputStream.read(data))!=-1){ outputStream.write(data, 0, len); } fileInputStream.close(); outputStream.close(); } }
接着来试试效果
nice,基本的效果都已经实现了,但是还是要优化之处,比如:
1、阅读IOUtis,把读写操作进行封装起来方便调用
package com.blb.utils; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; public class IOUtils { /** * 输入输出流读取操作封装 * @param inputStream * @param outputStream * @throws IOException */ public static void readAndWriter(InputStream inputStream, OutputStream outputStream) throws IOException { byte[] data = new byte[1024]; int len; while ((len=inputStream.read(data))!=-1){ outputStream.write(data, 0, len); } inputStream.close(); outputStream.close(); } /** * 下载配置 * @param resp * @param file * @param length * @throws UnsupportedEncodingException */ public static void downloadConfig(HttpServletResponse resp, String file, int length) throws UnsupportedEncodingException { String fileName = new String(file.getBytes(), "iso-8859-1"); resp.setContentType("application/octet-stream"); resp.setContentLength(length); resp.setHeader("Content-Disposition", "attachment;filename=" + fileName ); } }
2、下载前先判断文件是否存在
在DownloadServlet里添加如下代码:
if (!file1.exists()) { req.setAttribute("msg", "文件不存在"); req.getRequestDispatcher("index.jsp").forward(req, resp); return; } //判断文件是否存在
然后在index.jsp里加一个绑定数据${msg}实现传递
<h1>文件列表</h1> ${msg} <c:forEach items="${files}" var="file"> <a href="download?file=${file}">${file}</a><br> </c:forEach>
3、服务器重启后,文件列表丢失问题
第一次进来时,文件列表不能正常显示问题
package com.blb.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; @WebServlet("/index") public class IndexServlet extends HttpServlet { // String path = "D:/upload/"; @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { File dir = new File("D:/upload/"); String[] list = dir.list(); //把存放文件名集合的list放到session作用域中 req.getSession().setAttribute("files", list); resp.sendRedirect("index.jsp"); //重定向 } }
最后的最后,这个小项目到这里结束了,欢迎大家指正!!
- 点赞
- 收藏
- 关注作者
评论(0)