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. ...
随机推荐
- JVM探究之 —— 类加载过程
1. 类加载是什么 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 与那些在编译时需要进行连 ...
- Docker 安装 ActiveMQ
搜索 ActiveMQ 镜像 docker search activemq 获取 ActiveMQ 镜像 docker pull webcenter/activemq 查看本地镜像 docker im ...
- videojs使用技巧
1 初始化 Video.js初始化有两种方式. 1.1 标签方式 一种是在<video>标签里面加上class="video-js"和data-setup='{}'属性 ...
- C语言宏应用-------#define STR(X) #X
C语言宏应用-------#define STR(X) #X #:会把参数转换为字符串 #define STR(x) #x #define MAX 100 STR(MAX) 会被扩展成" ...
- Operation之结合操作符
startWith 该方法会在Observable序列开始之前插入一些事件元素. 即发生事件消息之前, 会发出这些预先插入的事件消息 Observable.of("2", &quo ...
- 安装centos docker ce
安装centos docker ce 移除旧的版本: $ sudo yum remove docker \ docker-client \ docker-client-latest \ docker- ...
- iOS - 在xib中UILabel文字如何换行
在换行的位置按住Option + Enter键即可换行
- Centos7根据yum源安装指定版本docker
yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mi ...
- java核心技术(卷一)
一,java基本程序设计结构: 1,在网页中运行的 Java 程序称为 applet. 要使用 applet ,需要启用 Java 的 Web 浏览器执行字节码. 2,jdk安装目录下的 src.zi ...
- android问题总结:
1. android:focusableInTouchMode="true" 属性: 控制 子view不获取焦点: <android.support.v4.widget. ...