案例:
文件下载需求:
一:页面显示超链接
二:点击超链接后弹出下载提示框
三:完成图片文件下载
分析:
一:超链接指向的资源如果能够浏览器解析,则在浏览器中显示,如果不能解析,则弹出下载提示框,不满足需求
二:任何资源都必须弹出下载提示框
三:使用响应头设置资源的打开方式
content-disposition:attachment;filename=xxx
步骤:
一:定义页面,编辑超链接href属性,指向servlet,传递资源名称filename
二:定义Servlet
一:获取文件名称
二:使用字节输入流加载文件进内存
三:指定response响应头:context-disposition:attachment;filename=xxx
四:将数据写出到response输出流
问题:
中文文件问题
解决思路:
一:获取客户端使用的浏览器版本信息
二:根据不同的版本信息,设置filename的编码方式不同
实现结果如图:
项目准备
一:使用maven管理jar包,添加依赖
<!--javaEE-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--jstl依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
二:前端页面代码:
<%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2020/3/3
Time: 18:13
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>下载文件</title>
<style>
a{
text-decoration: none;
}
</style>
</head>
<body>
<a href="/download?filename=亚远.png">下载图片</a>
<hr/>
<a href="/download?filename=a.avi">下载视频</a>
</body>
</html>
三:servlet代码实现问件下载:
package com.servlet01.servlet;
import com.servlet01.util.DownLoadUtil;
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;
/**
* package_name:com.servlet01.servlet
*
* @author:徐亚远 Date:2020/3/3 18:18
* 项目名:servlet-project
* Description:TODO
* Version: 1.0
**/
@WebServlet("/download")
public class DownLoad extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//一:获取请求参数,文件名称
String filename = req.getParameter("filename");
//二:使用字节输入流加载文件进内存
//2.1获取文件真实路径
ServletContext context = req.getServletContext();
String path = context.getRealPath("/WEB-INF/image/" + filename);
System.out.println("path:" + path);
//2.2用字节流关联
FileInputStream inputStream = new FileInputStream(path);
//3指定response响应头:content-disposition:attachment;filename=xxx
//3.1设置响应头类型 content-type
//获取mimeleix
String mimeType = context.getMimeType(filename);
resp.setHeader("content-type", mimeType);
//设置响应头打开方式
//解决中文文件名问题
//1:获取user-agent请求头
String agent = req.getHeader("user-agent");
//2:使用工具类方法编码文件名即可
filename = DownLoadUtil.getFileName(agent, filename);
resp.setHeader("content-disposition", "attachment;filename=" + filename);
//4将输入流的数据写出到输出流中
ServletOutputStream sos = resp.getOutputStream();
byte[] buff = new byte[1024 * 10];
int len = 0;
while ((len = inputStream.read(buff)) != -1) {
sos.write(buff, 0, len);
}
}
}
工具类:
package com.servlet01.util;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* package_name:com.servlet01.util
*
* @author:徐亚远 Date:2020/3/3 19:19
* 项目名:servlet-project
* Description:TODO
* Version: 1.0
**/
public class DownLoadUtil {
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")){
//火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B"+base64Encoder.encode(filename.getBytes("utf-8"))+"?=";
}else {
//其他浏览器
filename = URLEncoder.encode(filename,"utf-8" );
}
return filename;
}
}