一、文件下载原理
1、设置 response 响应头
2、读取文件 -- InputStream
3、写出文件 -- OutputStream
4、执行操作
5、关闭流 (先开后关)
二、实现代码
@RequestMapping(value="/downloadFile") public String downloads(HttpServletResponse response) throws Exception{ String path = "C:/"; String fileName = "default.png"; //1、设置response 响应头 response.reset(); response.setCharacterEncoding("UTF-8"); response.setContentType("multipart/form-data"); response.setHeader("Content-Disposition","attachment;fileName="+URLEncoder.encode(fileName, "UTF-8")); File file = new File(path,fileName); //2、 读取文件--输入流 InputStream input=new FileInputStream(file); //3、 写出文件--输出流 OutputStream out = response.getOutputStream(); byte[] buff =new byte[1024]; int index=0; //4、执行 写出操作 while((index= input.read(buff))!= -1){ out.write(buff, 0, index); out.flush(); } out.close(); input.close(); return null; } //注: 直接请求url: "/downloadFile",即可实现文件下载。 (需:C盘有一个 default.png 的文件)
其他实现代码:
//你只需要关注append函数里的a标签,这个a标签就是每个文件对应的下载按钮。其中basePath的定义为:String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; path的定义为:String path = request.getContextPath(); 这里稍作请求路径解释:先拿到服务器名,再是端口号(服务器+端口号下就是你发布到Tomcat的很多javaweb项目),再是上下文路径(该项目文件夹下),这样basePath路径下就是大家熟悉的META-INF,WEB-INF,index.jsp。以Servlet容器的角度看,这个basePath下其实是一个SpringIOC容器,里面有我写好的各个bean,Service与Controller对象(SpringMVC用于映射),相信熟悉Spring与SpringMVC的你们都知道这些。 @Controller @RequestMapping(value = "/youandme") public class youandmeController { @Autowired private MyDownload myDownload; @RequestMapping(value = "/downloadFile/{id}") public void downloadFile(@PathVariable("id") int id,HttpServletRequest request,HttpServletResponse response){ try { int userId = ((User)(request.getSession().getAttribute("user"))).getUserId(); myDownload.downloadSolve(id,request,response,userId); }catch (ServletException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } } //@PathVariable(“id”) int id得到请求URL中的参数id,是该文件相应信息在数据库的唯一标识。 package web.download; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import service.youandmeService; @Component public class MyDownload{ @Autowired private youandmeService youandmeService; public void downloadSolve(int id,HttpServletRequest request, HttpServletResponse response,int userId) throws ServletException, IOException { //根据文件id在数据库中获取文件名 String fileName = (youandmeService.showFileOfId(id)).getFileName(); //文件所在目录路径 String filePath = request.getSession().getServletContext().getRealPath("/")+"pluploadDir/"+userId+"/"; //得到该文件 File file = new File(filePath+fileName); if(!file.exists()){ System.out.println("Have no such file!"); return;//文件不存在就退出方法 } FileInputStream fileInputStream = new FileInputStream(file); //设置Http响应头告诉浏览器下载这个附件 response.setHeader("Content-Disposition", "attachment;Filename=" + URLEncoder.encode(fileName, "UTF-8")); OutputStream outputStream = response.getOutputStream(); byte[] bytes = new byte[2048]; int len = 0; while ((len = fileInputStream.read(bytes))>0){ outputStream.write(bytes,0,len); } fileInputStream.close(); outputStream.close(); } } //重要的注释都在代码中给出了。类头上的@Component注解是为了告诉SpringMVC,将这个写好的类注入到SpringIOC容器中以待使用(Controller就通过@Autowired注解自动装载了这个类并使用)。类中通过@Autowired装载了我用MyBatis与Spring封装的youandmeService对象,这个对象负责整个项目的数据库操作。 //再提一遍response.setHeader,这个是设置响应头信息,attachment中文是附件的意思,告诉浏览器去下载它;URLEncoder.encode解决文件名中文乱码问题。
三、使用spirng 自带的 ResponseEntity 实现
@RequestMapping(value="/downloadEntity") public ResponseEntity<byte[]> downloadsEntity(HttpServletRequest request) throws Exception{ String path = "C:/"; String fileName = "default.png"; File file=new File(path,fileName); if(!file.isFile()){ return null; } @SuppressWarnings("resource") InputStream input=new FileInputStream(file); byte[] buff=new byte[input.available()]; // 获取文件大小 input.read(buff) ; HttpHeaders headers=new HttpHeaders(); headers.add("Content-Disposition", "attachment;filename="+fileName); HttpStatus status=HttpStatus.OK; ResponseEntity<byte[]> entity=new ResponseEntity<byte[]>(buff,headers,status); return entity; }
四、前端页面
1、html页面直接下载:
<a href="/downloads/downloadFile">点击下载</a><br><br>
2、js 代码下载:
a. html:
<button id="btn_location">location下载</button><br><br>
b. js :
$("#btn_location").click(function(){ window.location.href="/downloads/downloadFile"; });
原文链接:https://blog.csdn.net/HaHa_Sir/article/details/79258556
原文链接:https://blog.csdn.net/qq_33290787/article/details/52334826
文章评论