上传图片到本地的代码
public void uploadFileToDisk(HttpServletRequest request, HttpServletResponse response, String baseDir) {
File dir = new File(baseDir);
if (!dir.exists()) {
dir.mkdirs();
}
List<FileItem> items = null;
try {
items = getFileItemList(request, response, dir);
} catch (Exception e) {
log.warn("服务器后台没有从请求中获取到上传文件的信息,异常信息:", e);
}
}
public static List<FileItem> getFileItemList(HttpServletRequest request, HttpServletResponse response, File baseDir) throws UnsupportedEncodingException, FileUploadException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存缓冲区,超过后写入临时文件
factory.setSizeThreshold(1024 * 512);
// 设置缓存文件路径,路径为空则不设置
if (baseDir != null) {
factory.setRepository(baseDir);
}
// 设置临时文件存储位置
ServletFileUpload upload = new ServletFileUpload(factory);
// 设置单个文件的最大上传值
upload.setFileSizeMax(10 * 1024 * 1024);
// 设置整个request的最大值
upload.setSizeMax(10002400000L);
upload.setHeaderEncoding("UTF-8");
List<FileItem> fileItems = new ArrayList<>();
if (request instanceof MultipartHttpServletRequest) {
MultiValueMap<String, MultipartFile> multipartFileMultiValueMap = ((MultipartHttpServletRequest) request).getMultiFileMap();
for (String key : multipartFileMultiValueMap.keySet()) {
List<MultipartFile> multipartFileList = multipartFileMultiValueMap.get(key);
if (CollectionUtils.isEmpty(multipartFileList)) {
continue;
}
for (MultipartFile multipartFile : multipartFileList) {
CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile)multipartFile;
fileItems.add(commonsMultipartFile.getFileItem());
}
}
} else {
fileItems = (List<FileItem>) upload.parseRequest(request);
}
return fileItems;
}
直接访问上传的路径就可以下载图片了。但是我们往往会包一层接口,以流的方式读取 url 的内容然后返回给前端,这么做的优点是:
这么做的一般代码为
void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = request.getParameter("file_name");
OutputStream out = response.getOutputStream();
String url = request.getParameter("file_path");
byte[] bytes;
// 读取流数据
VacationClient2 vc = new VacationClient2(2000, 5000);
byte[] bs = vc.getContentBytes(url);
// 一般返回的是 base64 串,但是有可能会返回一般的字符串,不需要做 base64 解码时做个判断处理一下
if (url.matches("^.*imgs\\.qunarzz\\.com.*\\.$")) {
bytes = bs;
} else {
String newString = new String(bs);
// 替换所有的空格到+
newString = newString.replaceAll(" ", "+");
bytes = new BASE64Decoder().decodeBuffer(newString);
}
downloadFileUnderHttps(request, response, fileName, bytes);
out.write(bytes);
out.flush();
out.close();
}
讲一下 base64 是什么:
为什么要使用 Base64?
总之,使用 Base64 编码可以方便地将二进制数据转换为可打印的 ASCII 字符,以便在网络传输或存储到文本文件中
为了保证所输出的编码位可读字符,Base64 制定了一个编码表,以便进行统一转换。编码表的大小为 2^6=64,这也是 Base64 名称的由来
在 Base64 中的可打印字符包括字母 A-Z、a-z、数字 0-9,这样共有 62 个字符,此外两个可打印符号在不同的系统中而不同
以下是 Base64 编码的基本步骤:
Base64 编码具有以下特点:
此外还有一个问题,Base64 加密后的数据通过 http 传输后,后台接收到的数据可能会出现空格的问题。这个问题还不知道具体原因
最后,贴一下响应头的代码:
public static void downloadFileUnderHttps(HttpServletRequest request,
HttpServletResponse response,
String filename, byte[] fileBytes) throws UnsupportedEncodingException {
String agent = request.getHeader("User-Agent");
filename = filename.replaceAll("filename=", "");
if (agent != null && agent.indexOf("Windows") != -1) {
filename = new String(filename.getBytes("GB2312"), "ISO_8859_1");
} else {
filename = new String(filename.getBytes("UTF-8"), "ISO_8859_1");
}
// 通过文件开头获取文件类型
String contentType = FileTypeUtil.getFileContentType(fileBytes);
if (StringUtils.isNotBlank(contentType)) {
response.setContentType(contentType);
response.addHeader("Content-Disposition", "inline; filename=\"" + filename + "\"");
} else {
response.setContentType("APPLICATION/OCTET-STREAM");
response.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
response.setHeader("Content-Transfer-Encoding", "binary");
}
response.setCharacterEncoding("UTF-8");
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "public");
}
常见的文件开头如下: