1. yaml 配置
spring-boot-plus:
# 是否启用ansi控制台输出有颜色的字体,local环境建议开启,服务器环境设置为false
enable-ansi: false
# 拦截器配置
interceptor-config:
resource-config:
include-path: ${spring-boot-plus.resource-access-patterns}
# 文件上传下载配置:/opt/DocumentCenter/QualityCollegeDocument
upload-path: ${file-system.qualityCollegeDocument}
# 资源访问路径
resource-access-path: QualityCollegeDocument/
# 资源访问路径匹配:QualityCollegeDocument/**
resource-access-patterns: ${spring-boot-plus.resource-access-path}**
# 资源访问全路径前缀:https://qestest.lei.com/dl/DocumentCenter/QualityCollegeDocument/
resource-access-url: ${file-system.downloadPre}/${spring-boot-plus.resource-access-path}
2. 下载和预览原理
目的:为了能在外网访问内网服务器的资源,所以必须有两个步骤:
1.虚拟映射:服务器内部资源隐射出来;
2.代理:外网能够访问映射的资源。
2.1 虚拟映射实现,实现下载和预览功能
【上传实际路径】
http://10.122.66.66/opt/DocumentCenter/QualityCollegeDocument/178a63c03e6.png 【无法直接访问】
【资源访问路径】
// 开通 81 端口,实现文件的下载
http://10.122.66.66:81/DocumentCenter/QualityCollegeDocument/178a63c03e6.png 【可以直接下载文件】
// 开通 82 端口,实现文件的预览
http://10.122.66.66:82/DocumentCenter/QualityCollegeDocument/178a63c03e6.png 【可以直接预览文件】
// 其他虚拟映射
/data/upload/178a617ad2e.png
https://10.122.66.66:8889/api/resource/178ab722c71.png
2.2 nginx代理
// nginx 代理下载路径
https://qestest.lei.com/dl ===》 http://10.122.66.66:81/【代理下载功能】
// nginx 代理预览路径
https://qestest.lei.com/fv ===》 http://10.122.66.66:82/【代理预览功能】
// 使用此代理后的路径,也可以实现文件的下载
https://qestest.lei.com/dl/DocumentCenter/QualityCollegeDocument/178a63c03e6.png 【可以直接下载文件】
// 使用此代理后的路径,也可以实现文件的预览
https://qestest.lei.com/fv/DocumentCenter/QualityCollegeDocument/178a63c03e6.png 【可以直接预览文件】
// 其他代理
https://10.122.66.66:8889/api/resource/178ab722c71.png
https://npidev.lei.com/api/api/resource/178ab722c71.png
3. 代码
3.1 Controller
/**
* 上传单个文件
*/
@PostMapping("/upload")
@Protected(Protected.Type.LOGIN)
@ApiOperation(value = "上传单个文件", notes = "上传单个文件", response = ApiResult.class)
public ApiResult<String> upload(@RequestParam("img") MultipartFile multipartFile) throws Exception {
log.info("multipartFile = " + multipartFile);
log.info("ContentType = " + multipartFile.getContentType());
log.info("OriginalFilename = " + multipartFile.getOriginalFilename());
log.info("Name = " + multipartFile.getName());
log.info("Size = " + multipartFile.getSize());
ApiResult<Map> upload = UploadUtil.upload(springBootPlusProperties.getUploadPath(), multipartFile);
if (upload.getData() == null) {
return ApiResult.fail(upload.getMsg());
}
Map resultMap = upload.getData();
if (resultMap.isEmpty()) {
return ApiResult.fail(ApiCode.UPLOAD_FAILED_EXCEPTION);
}
Date date = new Date();
FileDetail result = new FileDetail();
result.setFileName(resultMap.get("saveFileName").toString());
result.setFilePath(resultMap.get("filePath").toString());
result.setFileType(resultMap.get("fileFormat").toString());
result.setFileSize(Long.parseLong(resultMap.get("fileSize").toString()));
result.setUploadTime(date);
//将文件详情保存在数据库
fileDetailService.save(result);
// 上传成功之后,返回相对路径
String fileAccessPath = FileSystemProperties.getUrlPathPre() + resultMap.get("saveFileName").toString();
log.info("fileAccessPath:{}", fileAccessPath);
return ApiResult.ok(fileAccessPath);
}
3.2 UploadUtil
/**
* 上传文件,默认文件名格式,yyyyMMddHHmmssS
*
* @param uploadPath
* @param multipartFile
* @return
* @throws Exception
*/
public static ApiResult<Map> upload(String uploadPath, MultipartFile multipartFile) throws Exception {
return upload(uploadPath, multipartFile, new DefaultUploadFileNameHandleImpl());
}
/**
* 上传文件
*
* @param uploadPath 上传目录
* @param multipartFile 上传文件
* @param uploadFileNameHandle 回调
* @return
* @throws Exception
*/
public static ApiResult<Map> upload(String uploadPath, MultipartFile multipartFile, UploadFileNameHandle uploadFileNameHandle) {
ApiResult apiResult = new ApiResult();
// 截取文件类型; 这里可以根据文件类型进行判断
String fileFormat;
//获取文件大小
Long fileSize;
//获取文件上传路径
String filePath;
//保存文件名
String saveFileName;
// 获取输入流
InputStream inputStream = null;
try {
inputStream = multipartFile.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
// 文件保存目录
File saveDir = new File(uploadPath);
// 判断目录是否存在,不存在,则创建,如创建失败,则抛出异常
if (!saveDir.exists()) {
boolean flag = saveDir.mkdirs();
if (!flag) {
throw new RuntimeException("创建" + saveDir + "目录失败!");
}
}
String originalFilename = multipartFile.getOriginalFilename();
if (uploadFileNameHandle == null) {
saveFileName = new DefaultUploadFileNameHandleImpl().handle(originalFilename);
} else {
saveFileName = uploadFileNameHandle.handle(originalFilename);
}
File saveFile = new File(saveDir, saveFileName);
// 保存文件到服务器指定路径
Map resultMap = new HashMap();
try {
fileFormat = originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
if (!CommonConstant.FILE_TYPE_LIST.contains(fileFormat.toLowerCase())) {
apiResult.setMsg("File format can not be supported ! We can support the format such as :" + CommonConstant.FILE_TYPE_LIST.toString());
return apiResult;
}
FileUtils.copyToFile(inputStream, saveFile);
fileSize = saveFile.length();
filePath = saveFile.getPath();
log.info("saveFileName = " + saveFileName);
log.info("fileFormat = " + fileFormat);
log.info("fileSize = " + fileSize);
log.info("filePath = " + filePath);
resultMap.put("saveFileName", saveFileName);
resultMap.put("fileFormat", fileFormat);
resultMap.put("fileSize", fileSize);
resultMap.put("filePath", filePath);
} catch (IOException e) {
e.printStackTrace();
}
apiResult.setData(resultMap);
return apiResult;
}