一般会用在文件下载时,需要在浏览器中打开预览的场景,会有需求获取到对应文件的 mimeType
package cn.mrcode;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
/**
* 根据文件名获取 mimeType
*
* @author mrcode
* @date 2021/9/1 20:59
*/
public class MimeTypeUtil {
/**
* 流类型
*/
public static final String APPLICATION_OCTET_STREAM_VALUE = "application/octet-stream";
/**
* 根据文件名后缀获取 mimeType;
* <pre>
* 支持的类型如下:
* gif : image/gif
* bmp : image/bmp
* ico : image/x-icon
* jpeg : image/jpeg
* jpg : image/jpeg
* png : image/png
* zip : application/x-zip-compressed
* jsp : null
* pdf : application/pdf
* png : image/png
* jpg : image/jpeg
* mp4 : video/mp4
* flv : null
* ppt : application/vnd.ms-powerpoint
* pptx : application/vnd.openxmlformats-officedocument.presentationml.presentation
* xlsx : application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
* xls : application/vnd.ms-excel
* doc : application/msword
* docx : application/vnd.openxmlformats-officedocument.wordprocessingml.document
* txt : text/plain
* </pre>
*
* @return
*/
public static String get(String fileName) {
return get(Paths.get(fileName));
}
public static String get(String fileName, String defaultMimeType) {
final String mimeType = get(fileName);
return mimeType == null ? defaultMimeType : mimeType;
}
public static String get(Path filePath) {
try {
return Files.probeContentType(filePath);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static String get(Path filePath, String defaultMimeType) {
final String mimeType = get(filePath);
return mimeType == null ? defaultMimeType : mimeType;
}
public static void main(String[] args) {
final List<String> suffixs = Arrays.asList(
"gif", "bmp", "ico", "jpeg", "jpg", "png", "zip", "jsp", "pdf", "png", "jpg", "mp4", "flv", "ppt", "pptx", "xlsx", "xls", "doc", "docx", "txt"
);
for (int i = 0; i < suffixs.size(); i++) {
final String suffix = suffixs.get(i);
System.out.println(suffix + " : " + get(i + "." + suffix));
}
}
}
文件下载、预览
使用上面的工具类获取 contentType,然后按前端传递的参数 type 来判定是在浏览器内部打开?还是使用浏览器下载
// 设置文件大小
response.setContentLength((int) Files.size(path));
response.setContentType(MimeTypeUtil.get(path, MimeTypeUtil.APPLICATION_OCTET_STREAM_VALUE));
// 文件名有中文,先编码
String fileNameEncod = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
String contentDispositionValue = StrUtil.format("{}; filename=\"{}\"; filename*=utf-8''{}",
type == 1 ? "inline" : "attachment", // inline 浏览器内部打开,attachment 下载
fileNameEncod, fileNameEncod
);
response.setHeader("Content-Disposition", contentDispositionValue);
// java.nio.file.Files
Files.copy(path, response.getOutputStream());
openJdk 无法获取到任何类型
原因:
- 服务器上使用 OpenJdk:使用上面的写法无法获取到任何类型,应该是对应的配置文件被阉割了
- 本地使用 OracleJdk:可以正常获取
故而直接改成手动获取的返回了
package com.runshopstore.crmbe.common_service;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.StrUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
/**
* 根据文件名获取 mimeType
*
* @author mrcode
* @date 2021/9/1 20:59
*/
@Slf4j
public class MimeTypeUtil {
private static Map<String, String> map = new HashMap<>();
static {
map.put("gif", "image/gif");
map.put("bmp", "image/bmp");
map.put("ico", "image/x-icon");
map.put("jpeg", "image/jpeg");
map.put("jpg", "image/jpeg");
map.put("png", "image/png");
map.put("zip", "application/x-zip-compressed");
map.put("jsp", "null");
map.put("pdf", "application/pdf");
map.put("png", "image/png");
map.put("jpg", "image/jpeg");
map.put("mp4", "video/mp4");
map.put("flv", "null");
map.put("ppt", "application/vnd.ms-powerpoint");
map.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
map.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
map.put("xls", "application/vnd.ms-excel");
map.put("doc", "application/msword");
map.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
map.put("txt", "text/plain");
}
/**
* 流类型
*/
public static final String APPLICATION_OCTET_STREAM_VALUE = "application/octet-stream";
/**
* 根据文件名后缀获取 mimeType;
* <pre>
* 支持的类型如下:
* gif : image/gif
* bmp : image/bmp
* ico : image/x-icon
* jpeg : image/jpeg
* jpg : image/jpeg
* png : image/png
* zip : application/x-zip-compressed
* jsp : null
* pdf : application/pdf
* png : image/png
* jpg : image/jpeg
* mp4 : video/mp4
* flv : null
* ppt : application/vnd.ms-powerpoint
* pptx : application/vnd.openxmlformats-officedocument.presentationml.presentation
* xlsx : application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
* xls : application/vnd.ms-excel
* doc : application/msword
* docx : application/vnd.openxmlformats-officedocument.wordprocessingml.document
* txt : text/plain
* </pre>
*
* @return
*/
public static String get(String fileName) {
return get(Paths.get(fileName));
}
public static String get(String fileName, String defaultMimeType) {
final String mimeType = get(fileName);
return mimeType == null ? defaultMimeType : mimeType;
}
@SneakyThrows
public static String get(Path filePath) {
final String fileName = filePath.getFileName().toString();
final String extName = FileNameUtil.extName(fileName);
return map.get(extName);
//return Files.probeContentType(filePath); // openJDK 无法获取到对应的类型
}
public static String get(Path filePath, String defaultMimeType) {
final String mimeType = get(filePath);
return mimeType == null ? defaultMimeType : mimeType;
}
public static void main(String[] args) {
final List<String> suffixs = Arrays.asList(
"gif", "bmp", "ico", "jpeg", "jpg", "png", "zip", "jsp", "pdf", "png", "jpg", "mp4", "flv", "ppt", "pptx", "xlsx", "xls", "doc", "docx", "txt"
);
for (int i = 0; i < suffixs.size(); i++) {
final String suffix = suffixs.get(i);
// System.out.println(suffix + " : " + get(i + "." + suffix));
System.out.println(StrUtil.format("map.put(\"{}\",\"{}\");", suffix, get(i + "." + suffix)));
}
}
}