文件下载需求:

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. Microsoft.Owin 使用 文件服务

    添加引用: <package id="Microsoft.Owin" version="4.0.1" targetFramework="net4 ...

  2. Centos7下安装ORACLE 11g,弹窗不显示

    Centos7下安装ORACLE 11gR2,弹窗不显示,安装界面显示为灰色. 解决方法:执行安装时带上一下参数 ./runInstaller -jreLoc /etc/alternatives/jr ...

  3. Jenkins 发布项目到远程服务器上

    最近公司弄一个项目,jenkins在本地服务器,需要打包发布到远程的阿里云服务器上,弄了好一阵子. 这里记录下中间的几个坑. 这个Remote DIrectory 很重要,到时候时候会拷贝到这个目录下 ...

  4. Nginx warn:an upstream response is buffered to a temporary file

    我通过nginx下载文件,error.log中出现如下警告日志:warn:an upstream response is buffered to a temporary file  . 虽然网上各种例 ...

  5. bootcss 之 .table-hover 类 鼠标悬停

    通过添加 .table-hover 类可以让 <tbody> 中的每一行对鼠标悬停状态作出响应. <table class="table table-hover" ...

  6. 工控随笔_24_西门子TIA 博图硬件目录的更新

    西门子博图软件,不但体积庞大,功能也很复杂,与经典的Step7相比,如果不是经常使用,一般都会有一种很难使用的感觉. 而且相比原来的Step7操作有点不太一样.这里简单的说一下硬件目录的更新. 有两种 ...

  7. 使用自定义注解和AOP管理shiro权限

    一.场景 在使用shiro框架的时候,遇到了这样的需求:本系统有多个用户,每个用户分配不同角色,每个角色的权限也不一致.比如A用户拥有新闻列表的增删改查权限,而B用户只有查看新闻列表的权限,而没有删除 ...

  8. CSS选择子简明参考

    Type Selector Example h1 { } Description Selects an HTML tag/element. Universal selector Example * { ...

  9. ejs不能读取js变量??????

    一.问题描述 用express搭了一个nodejs服务端,为了测试接口数据是否能够正常输出,用ejs作为模版引擎的html文件写js发请求. 1.请求正常,能在network看到,但是没有输出cons ...

  10. [数据结构 - 第6章] 树之链式二叉树(C语言实现)

    一.什么是二叉树? 1.1 定义 二叉树,是度为二的树,二叉树的每一个节点最多只有二个子节点,且两个子节点有序. 1.2 二叉树的重要特性 (1)二叉树的第 i 层上节点数最多为 2n-1: (2)高 ...