之前看很多博客都是通过 判断userAgent来处理文件名的中文乱码问题,如下
if (userAgent.indexOf("MSIE")!=-1 || userAgent.indexOf("Trident")!=-1 || userAgent.indexOf("Edge")!=-1 ) { // ie
fileName = new String(fileName.getBytes("GBK"), "iso-8859-1");
} else if (null != userAgent && -1 != userAgent.indexOf("Mozilla")) { // 火狐,chrome等
fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
}
但博主实际开发中发现,这种也不是百分之百有效,最简单粗暴的方式就是把fileName 先BASE64编码存为url,然后下载时候再把fileName用BASE64解码,就可以规避浏览器对中文编码不一致的问题了,代码如下:
package com.nercel.cyberhouse.ws.sns;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import com.alibaba.fastjson.JSON;
import com.nercel.cyberhouse.util.ServerConfig;
import com.nercel.cyberhouse.vo.UFile;
import com.nercel.cyberhouse.vo.UploadFile;
import java.util.regex.*;
@Controller
@RequestMapping("sns")
public class FileUpload {
private String CYBERHOUSE_PATH = ServerConfig.get("cyberhouse.root");
@RequestMapping(value = "/uploadFile", produces = "text/plain; charset=utf-8")
public @ResponseBody String uploadFile(@RequestParam(value = "file", required = false) MultipartFile file,int userId,HttpServletRequest request, HttpServletResponse response) {
UploadFile upFile = new UploadFile();
String path = request.getSession().getServletContext().getRealPath("upload/sns/"+userId+"/");
// String fileName = StringFilter(file.getOriginalFilename());
String fileName = file.getOriginalFilename();
String ext=fileName.substring(fileName.lastIndexOf(".")+1);
if(file.getSize()>1024*1024*50){
upFile.setCode(1);
upFile.setMsg("单个文件/图片大小不能超过50M!");
return JSON.toJSONString(upFile);
}
String name=UUID.randomUUID().toString()+"."+ext;
String downLoadPath=path+"/"+name;
File targetFile = new File(path,name);
if(!targetFile.exists()){
targetFile.mkdirs();
}
try {
file.transferTo(targetFile);
upFile.setCode(0);
UFile uf=new UFile();
uf.setName(fileName);
byte[] b = null;
b = fileName.getBytes("utf-8");
uf.setSrc(CYBERHOUSE_PATH+"/sns/downLoadFile?downLoadPath="+downLoadPath+"&fileName="+new BASE64Encoder().encode(b));
upFile.setData(uf);
} catch (Exception e) {
e.printStackTrace();
}
return JSON.toJSONString(upFile);
}
@RequestMapping("/downLoadFile")
public void downLoadFile(String downLoadPath, String fileName,HttpServletResponse response,HttpServletRequest request) throws UnsupportedEncodingException {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
byte[] b = null;
String resultFileName = null;
BASE64Decoder decoder = new BASE64Decoder();
try {
b = decoder.decodeBuffer(fileName);
} catch (IOException e1) {
e1.printStackTrace();
}
resultFileName = new String(b, "utf-8");
try {
response.setCharacterEncoding("UTF-8");
long fileLength = new File(downLoadPath).length();
String userAgent = request.getHeader("User-Agent");
response.setHeader("Content-disposition", "attachment; filename="+new String(resultFileName.getBytes("gbk"),"iso-8859-1"));
response.setContentType("application/x-download;");
response.setHeader("Content-Length", String.valueOf(fileLength));
bis = new BufferedInputStream(new FileInputStream(downLoadPath));
bos = new BufferedOutputStream(response.getOutputStream());
byte[] buff = new byte[2048];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
bos.flush();
} catch (Exception e) {
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 过滤特殊字符
public static String StringFilter(String str) throws PatternSyntaxException{
// 清除掉所有特殊字符和空格
String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\]<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、? ]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.replaceAll("").trim();
}
//layui上传文件公共服务
@RequestMapping(value = "/upload", produces = "text/plain; charset=utf-8")
public @ResponseBody String upload(@RequestParam(value = "file", required = false) MultipartFile file,HttpServletRequest request, HttpServletResponse response) {
UploadFile upFile = new UploadFile();
String msg="上传失败!";
long fileSize = file.getSize();
System.out.println("fileSize="+fileSize);
if(fileSize>2097152){
upFile.setCode(1);
upFile.setMsg("上传文件不能超过2M!");
return JSON.toJSONString(upFile);
}
String fileName = StringFilter(file.getOriginalFilename());
String fileType= fileName.substring(fileName.lastIndexOf(".")+1);
Date now = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");//可以方便地修改日期格式
String today = dateFormat.format(now);
String path = request.getSession().getServletContext().getRealPath("upload/layuiUploads/"+fileType+"/"+today);
String name=UUID.randomUUID().toString()+fileName;
String downLoadPath=path+"/"+name;
File targetFile = new File(path,name);
if(!targetFile.exists()){
targetFile.mkdirs();
}
try {
file.transferTo(targetFile);
upFile.setCode(0);
UFile uf=new UFile();
uf.setName(fileName);
uf.setSrc(CYBERHOUSE_PATH+"/sns/downLoadFile?downLoadPath="+downLoadPath+"&fileName="+fileName);
upFile.setData(uf);
msg="上传成功!";
upFile.setMsg(msg);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(JSON.toJSONString(upFile));
return JSON.toJSONString(upFile);
}
}