解决浏览器下载文件时中文文件名乱码的问题
很多时候我们需要在后台为前端提供文件下载的功能,但是当文件名中有中文时我们不能直接将文件名返回,需要对中文的文件名进行处理后再返回。
一、文件下载controller代码
import com.alibaba.fastjson.JSON;
import com.wang.mygateway.myapi.dto.BaseResponse;
import com.wang.mygateway.serviceportal.utils.DownLoadUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@RestController
@RequestMapping("/files")
public class FileController {
@RequestMapping("/download/{fileId}")
public void downloadFile(HttpServletRequest request, HttpServletResponse response, @PathVariable("fileId") String fileId) throws IOException {
//根据fileId从数据库获取filePath,省略。。。。
String filePath = "E:\\账号.txt";
File file = new File(filePath);
ServletOutputStream stream = null;
try{
stream = response.getOutputStream();
response.reset();
response.setContentType("multipart/form-data");
response.setContentLength((int)file.length());
String agent = request.getHeader("user-agent");
String fileName = "";
if (null != agent){
fileName = DownLoadUtils.getFileName1(agent,file.getName());
}else{
fileName = new String(file.getName().getBytes("utf-8"),"ISO-8859-1");
}
response.addHeader("Content-Disposition","attachment;filename="+fileName);
byte[] bytes = null;
if (file.exists()&&file.isFile()&&file.canRead()){
InputStream fileInputStream = new FileInputStream(file);
long length = file.length();
bytes = length > 0 ? IOUtils.toByteArray(fileInputStream,length) : IOUtils.toByteArray(fileInputStream);
}
stream.write(bytes);
stream.flush();
} catch (Exception e){
this.writeResponse(response,404,"FILE000001","文件不存在");
return;
} finally {
if (null != stream){
stream.close();
}
}
}
private void writeResponse(HttpServletResponse response,int statusCode,String retCode,String retMsg) throws IOException {
BaseResponse baseResponse = new BaseResponse();
baseResponse.setCode(retCode);
baseResponse.setMsg(retMsg);
response.setStatus(statusCode);
response.setContentType("application/json");
response.setHeader("Access-Control-Allow-Origin","*");
response.getOutputStream().write(JSON.toJSONString(baseResponse,true).getBytes());
}
}
二、文件名处理工具类
//BASE64Encoder类:jdk1.8及之前能用
import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class DownLoadUtils {
/**
* 该方法要求JDK8及以下,可以针对不同的浏览器做不同的编码。
* @param agent
* @param filename
* @return
* @throws UnsupportedEncodingException
*/
public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
if (agent.contains("MSIE")||agent.contains("Trident")) {
// 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;
}
/**
* 能满足大多数浏览器,并且不要求JDK版本,建议使用该方法。
* @param agent
* @param filename
* @return
* @throws UnsupportedEncodingException
*/
public static String getFileName1(String agent, String filename) throws UnsupportedEncodingException {
if (agent.contains("MSIE")||agent.contains("Trident")) {
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else {
// 其它浏览器
filename = new String(filename.getBytes("utf-8"),"ISO-8859-1");
}
return filename;
}
}