Java 之 Response 文件下载案例
文件下载需求:
1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载
分析过程:
1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
2. 任何资源都必须弹出下载提示框
3. 使用响应头设置资源的打开方式:
content-disposition:attachment;filename=xxx
步骤:
1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
2. 定义Servlet
1. 获取文件名称
2. 使用字节输入流加载文件进内存
3. 指定response的响应头: content-disposition:attachment;filename=xxx
4. 将数据写出到response输出流
代码实现:
下载页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body> <a href="/day13/img/狐狸.jpg">图片1</a> <a href="/day13/img/2.jpg">图片2</a> <a href="/day13/img/1.avi">视频</a>
<hr> <a href="/day13/downloadservlet?filename=狐狸.jpg">图片1</a> <a href="/day13/downloadservlet?filename=2.jpg">图片2</a> <a href="/day13/downloadservlet?filename=1.avi">视频</a> </body>
</html>
DownLoadServlet 类
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException; @WebServlet("/downloadservlet")
public class downloadservlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1获取请求参数,文件名称
String filename = request.getParameter("filename"); //2使用字节输入流加载文件进内存
// 2.1 找文件服务器路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/img/" + filename); //2.2 使用字节流关联
FileInputStream fis = new FileInputStream(realPath); //3 设置 response 的响应头
// 3.1 设置响应头类型:content-type
String mimeType = servletContext.getMimeType(filename);
response.setHeader("content-type",mimeType);
// 3.2 设置响应头打开方式:content-disposition response.setHeader("content-disposition","attachment;filename="+filename); // 4. 将输入流的数据写出到输出流中
ServletOutputStream sos = response.getOutputStream(); byte[] buff = new byte[1024*8];
int len = 0; while((len = fis.read(buff)) != -1) {
sos.write(buff,0,buff.length);
} // 关闭流对象
fis.close();
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
上面的案例中发现,当下载的文件名字是中文的时候,下载的时候会出现乱码。
文件名中文乱码问题
解决思路:
(1)获取客户端使用的浏览器版本信息
(2)根据不同的版本信息,设置 filename 的编码方式不同
编码工具类:
使用 Base64 编码,需要导入 commons-codec-1.13.jar 包。
package cn.itcast.download; import org.apache.commons.codec.binary.Base64; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; public class DownLoadUtils { public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
if (agent.contains("MSIE")) {
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
Base64 base64Encoder = new Base64();
// 火狐浏览器
//BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
}
DownLoadServlet 类(改进):
package cn.itcast.download; import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException; @WebServlet("/downloadservlet")
public class downloadservlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1获取请求参数,文件名称
String filename = request.getParameter("filename"); //2使用字节输入流加载文件进内存
// 2.1 找文件服务器路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/img/" + filename); //2.2 使用字节流关联
FileInputStream fis = new FileInputStream(realPath); //3 设置 response 的响应头
// 3.1 设置响应头类型:content-type
String mimeType = servletContext.getMimeType(filename);
response.setHeader("content-type",mimeType);
// 3.2 设置响应头打开方式:content-disposition // 3.3 解决中文文件名问题
// 1 获取 user-agent 请求头
String agent = request.getHeader("user-agent");
// 2 使用工具类方法编码文件即可
filename = DownLoadUtils.getFileName(agent, filename); response.setHeader("content-disposition","attachment;filename="+filename); // 4. 将输入流的数据写出到输出流中
ServletOutputStream sos = response.getOutputStream(); byte[] buff = new byte[1024*8];
int len = 0; while((len = fis.read(buff)) != -1) {
sos.write(buff,0,buff.length);
} // 关闭流对象
fis.close();
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
Java 之 Response 文件下载案例的更多相关文章
- request和response文件下载案例
一.需求分析 * 文件下载需求: 1. 页面显示超链接 2. 点击超链接后弹出下载提示框 3. 完成图片文件下载 * 分析: 1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析 ...
- Java中都通用文件下载(ContentType、文件头、response、out四步骤)
Java中都通用文件下载(ContentType.文件头.response.out四步骤) 新浪微博:IT国子监(记得关注噢) http://weibo.com/itguozijian 我们就直接 ...
- Java虚拟机类加载机制——案例分析
转载: Java虚拟机类加载机制--案例分析 在<Java虚拟机类加载机制>一文中详细阐述了类加载的过程,并举了几个例子进行了简要分析,在文章的最后留了一个悬念给各位,这里来揭开这个悬 ...
- Java学生管理系统项目案例
这是一个不错的Java学生管理系统项目案例,希望能够帮到大家的学习吧. 分代码如下 package com.student.util; import java.sql.Connection; impo ...
- Java多态面试题案例几解题思路
---恢复内容开始--- Java多态面试题案例几解题思路 这道题是来自别人,先开始看到题很懵,后来有自己的思路: class A { public String show(D obj){ retur ...
- java基础-多线程应用案例展示
java基础-多线程应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.两只熊,100只蜜蜂,蜜蜂每次生产的蜂蜜量是1,罐子的容量是30,熊在罐子的蜂蜜量达到20的时候 ...
- Java基础-数据类型应用案例展示
Java基础-数据类型应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.把long数据转换成字节数组,把字节数组数据转换成long. /* @author :yinz ...
- JAVA WEB项目开发案例精粹
http://www.blogjava.net/zongbao/archive/2012/07/24/383884.htmlJAVA WEB项目开发案例精粹.pdf main Alt + / => ...
- zabbix java gateway配置实战案例
zabbix java gateway配置实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.部署tomcat服务 博主推荐阅读: CentOS: https://www. ...
随机推荐
- DVT JetBrains License Server(JetBrains授权服务器)2018 v1.1 最新版 含32位/64位
DVT JetBrains License Server是JetBrains系列软件授权服务器,支持2017版本得jetbrains pycharm,JetBrainswebstorm,JetBrai ...
- Nginx的configure脚本支持选项整理
在不同版本间,选项可能会有些许变化,请总是使用./configure –help命令来检查当前的选项列表. --prefix=<PATH> #Nginx安装路径.如果没有指定,默认为 /u ...
- JAVA中try、catch、finally带return的执行顺序总结
异常处理中,try.catch.finally的执行顺序,大家都知道是按顺序执行的.即,如果try中没有异常,则顺序为try→finally,如果try中有异常,则顺序为try→catch→final ...
- 一次升级jar包遇到的空指针异常
今天自己在升级公司的一个jar后,一直报空指针异常.代码如下 package com.zhuanche.http; import com.alibaba.fastjson.JSON; import c ...
- react 常用组件整理
0.es6语法糖 deptList = deptnameList.filter(item => item.rel ===this.state.thUser.orgId);//返回一个新的数组对象 ...
- 一款新的好用的SSH工具——FinalShell
FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还是功能强大的开发,运维工具,充分满足开发,运维需求.特色功能:免费海外服务器远程桌面加速,ssh加速,双边tcp加速,内网穿 ...
- 【layui】获取layui弹窗的index并关闭
var index = parent.layer.getFrameIndex(window.name); //获取窗口索引 parent.layer.close(index); // 关闭当前laye ...
- 一个".java"源文件中是否可以包括多个类(不包括内部类)
开通好几个月博客了,但是一直没有时间写,这一段时间准备开始复习了,以后准备好好写博客了,会从基础的内容开始. 一个".java"源文件中可以定义多个类,但最多只能定义一个publi ...
- Spring Boot 项目的 API 接口防刷
首先是写一个注解类 拦截器中实现 注册到springboot中 在Controller中加入注解 说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考 一,技术要点:springbo ...
- opencv之重映射
好久没写呆码了 今天发个重映射 #include "opencv2/video/tracking.hpp" #include "opencv2/imgproc/imgpr ...