文件下载需求:

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 文件下载案例的更多相关文章

  1. request和response文件下载案例

    一.需求分析 * 文件下载需求: 1. 页面显示超链接 2. 点击超链接后弹出下载提示框 3. 完成图片文件下载 * 分析: 1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析 ...

  2. Java中都通用文件下载(ContentType、文件头、response、out四步骤)

    Java中都通用文件下载(ContentType.文件头.response.out四步骤) 新浪微博:IT国子监(记得关注噢) http://weibo.com/itguozijian   我们就直接 ...

  3. Java虚拟机类加载机制——案例分析

    转载: Java虚拟机类加载机制--案例分析   在<Java虚拟机类加载机制>一文中详细阐述了类加载的过程,并举了几个例子进行了简要分析,在文章的最后留了一个悬念给各位,这里来揭开这个悬 ...

  4. Java学生管理系统项目案例

    这是一个不错的Java学生管理系统项目案例,希望能够帮到大家的学习吧. 分代码如下 package com.student.util; import java.sql.Connection; impo ...

  5. Java多态面试题案例几解题思路

    ---恢复内容开始--- Java多态面试题案例几解题思路 这道题是来自别人,先开始看到题很懵,后来有自己的思路: class A { public String show(D obj){ retur ...

  6. java基础-多线程应用案例展示

    java基础-多线程应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.两只熊,100只蜜蜂,蜜蜂每次生产的蜂蜜量是1,罐子的容量是30,熊在罐子的蜂蜜量达到20的时候 ...

  7. Java基础-数据类型应用案例展示

    Java基础-数据类型应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.把long数据转换成字节数组,把字节数组数据转换成long. /* @author :yinz ...

  8. JAVA WEB项目开发案例精粹

    http://www.blogjava.net/zongbao/archive/2012/07/24/383884.htmlJAVA WEB项目开发案例精粹.pdf main Alt + / => ...

  9. zabbix java gateway配置实战案例

    zabbix java gateway配置实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.部署tomcat服务 博主推荐阅读: CentOS: https://www. ...

随机推荐

  1. Oracle 行转列 动态出转换的列

    本文链接:https://blog.csdn.net/Huay_Li/article/details/82924443 10月的第二天,前天写了个Oracle中行转列的pivot的基本使用方法,然后, ...

  2. pandas.DataFrame.sample随机抽样

    https://study.163.com/course/courseMain.htm?courseId=1006383008&share=2&shareId=400000000398 ...

  3. 大数据常见端口汇总-hadoop、hbase、hive、spark、kafka、zookeeper等(持续更新)

    常见端口汇总:Hadoop:        50070:HDFS WEB UI端口    8020 : 高可用的HDFS RPC端口    9000 : 非高可用的HDFS RPC端口    8088 ...

  4. Spring-boot +Shiro 导致事务无效

    今天在开发过程中,遇到一个情况,就是事务事务,同项目的别的service都在事务中,可以就是有一个事务失效. 排除了各种情况 1.检查数据库的引擎是否是innoDB 2.方法是否为public 3.这 ...

  5. spring boot启动无法访问controller

    如题,检测 一.启动类Application是不是在最上一级,默认扫描启动类平级和下级目录的bean 二.启用内置Tomcat,注释掉 scope <dependency> <gro ...

  6. ubuntu16.04+cuda8.0+cudnn6.0安装mxnet(极简!+成功!)

    安装MXNet 1.安装 CUDA8.0对应的mxnet版本是mxnet-cu80(同理如果是CUDA9.0对应版本则是mxnet-cu90). 如果pip安装过慢,请参考 Ubuntu16.10下配 ...

  7. cube-ui按钮配合toast单例模式应用

    <template> <div> <cube-button icon="cubeic-right" @click="goNext" ...

  8. Linux 就该这么学 CH04 VIM编辑器和Shell命令脚本

    0 概述 1 Vim编辑器 在linux 中一切都是文件,而配置一个服务就是修改其配置文件的参数. vim 编辑器有三种模式:命令模式,末行模式和编辑模式. 命令模式:控制光标移动,对文件进行操作. ...

  9. 使用Docker Compose搭建Service Mesh

    使用Docker Compose搭建Service Mesh 本文将介绍如何使用Docker Compose搭建Istio.Istio号称支持多种平台(不仅仅Kubernetes).然而,官网上非基于 ...

  10. Linux安装kafka2.3.1基于Scala2.12

    一,先从官网下载:http://kafka.apache.org/downloads 二,解压压缩包(虽然后缀是tgz,但和gz解压方式一样):然后mv kafka_2.12-2.3.1 /usr/l ...