一. 中文文件下载
1. 新建一个DownloadLuanMa的Web工程
2. 在WebContent下新建一个Download目录, 下面放一个中文文件
3. 新建一个index.html
4. 编写index.html
5. 新建一个DownloadLuanMa.java类
6. 编写DownloadLuanMa.java
package com.lywgames.myservlet;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownloadLuanMa extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取文件名字
String filename = new String(req.getParameter("filename").getBytes("ISO8859-1"), "UTF-8");
// 让浏览器收到这份资源的时候, 以下载的方式提醒用户, 而不是直接展示。
resp.setHeader("Content-Disposition", "attachment; filename="+filename);
// 获取这个文件在Tomcat里面的绝对路径地址
String path = getServletContext().getRealPath("Download/" + filename);
InputStream is = new FileInputStream(path);
OutputStream os = resp.getOutputStream();
int len = 0 ;
byte[] buffer = new byte[1024];
while((len = is.read(buffer)) != -1){
os.write(buffer, 0, len);
}
os.close();
is.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
5. 编写web.xml
6. 部署访问
二. 解决中文乱码
1. 浏览器接受到我们的中文文件名字, 会进行一次URLDecoder的解码, 因此我们在返回文件名字的时候需要一次URLEncoder的编码。
2. 如果是IE或者Chrome, 使用的是URLDecoder的解码方式。 如果是Firefox, 使用Base64的解码方式。因此我们在返回文件名字的时候需要针对浏览器类型, 给中文文件名字进行URLEncoder或者BASE64Encoder的编码。
3. 修改我们的DownloadLuanMa.java
package com.lywgames.myservlet;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sun.misc.BASE64Encoder;
public class DownloadLuanMa extends HttpServlet {
private static final long serialVersionUID = 1L;
public static String base64EncodeFileName(String fileName) {
BASE64Encoder base64Encoder = new BASE64Encoder();
try {
return "=?UTF-8?B?" + new String(base64Encoder.encode(fileName.getBytes("UTF-8"))) + "?=";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取文件名字
String filename = new String(req.getParameter("filename").getBytes("ISO8859-1"), "UTF-8");
// 获取来访的客户端类型
String clientType = req.getHeader("User-Agent");
System.out.println(clientType + "\r\n" + base64EncodeFileName(filename));
// 让浏览器收到这份资源的时候, 以下载的方式提醒用户, 而不是直接展示。
if(clientType.contains("Firefox")){
resp.setHeader("Content-Disposition", "attachment; filename="+base64EncodeFileName(filename));
}else{
resp.setHeader("Content-Disposition", "attachment; filename="+URLEncoder.encode(filename, "UTF-8"));
}
// 获取这个文件在Tomcat里面的绝对路径地址
String path = getServletContext().getRealPath("Download/" + filename);
InputStream is = new FileInputStream(path);
OutputStream os = resp.getOutputStream();
int len = 0 ;
byte[] buffer = new byte[1024];
while((len = is.read(buffer)) != -1){
os.write(buffer, 0, len);
}
os.close();
is.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4. 部署运行, 使用IE浏览器下载, 中文名字显示正常
5. 使用Chrome浏览器下载, 中文名字显示正常
6. 使用Firefox浏览器下载, 中文名字显示正常