Commit 6e65d505 authored by huangcb's avatar huangcb

新增文件下载功能接口

parent 9c4a1590
package com.esv.freight.file.module.download;
import com.esv.freight.file.module.upload.service.FileMetaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
/**
* @description: 文件下载Controller
* @project: freight-file-service
* @name: com.esv.freight.file.module.download.DownloadController
* @author: 黄朝斌
* @email: huangchaobin@esvtek.com
* @createTime: 2020/04/14 17:06
* @version:1.0
*/
@Slf4j
@RestController
@RequestMapping("/download")
public class DownloadController {
private FileMetaService fileMetaService;
@Autowired
public DownloadController(FileMetaService fileMetaService) {
this.fileMetaService = fileMetaService;
}
/**
* description 文件下载
* param [id, response]
* return com.esv.freight.file.common.response.EResponse
* author Administrator
* createTime 2020/04/14 17:25
**/
@GetMapping("/direct/{id}")
public void directDownload(@PathVariable("id") String id, HttpServletResponse response) {
fileMetaService.directDownload(id, response);
}
}
......@@ -65,7 +65,7 @@ public class UploadController {
* createTime 2020/04/14 14:57
**/
void checkFile(FileForm fileForm) throws EException {
String[] types = FILE_REGISTER.split(",");
String[] types = FILE_REGISTER.trim().replaceAll(",", ",").split(",");
String type;
JSONObject fileTypeJson = new JSONObject();
for (int i = 0; i < types.length; i++) {
......
......@@ -6,6 +6,8 @@ import com.esv.freight.file.module.upload.entity.FileMetaEntity;
import com.esv.freight.file.module.upload.form.FileForm;
import com.esv.freight.file.module.upload.vo.FileVO;
import javax.servlet.http.HttpServletResponse;
/**
* 文件元数据表
*
......@@ -24,5 +26,14 @@ public interface FileMetaService extends IService<FileMetaEntity> {
**/
FileVO uploadFile(FileForm fileForm) throws EException;
/**
* description 终端下载文件
* param [id, response]
* return void
* author Administrator
* createTime 2020/04/14 17:24
**/
void directDownload(String id, HttpServletResponse response);
}
package com.esv.freight.file.module.upload.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.esv.freight.file.common.exception.EException;
import com.esv.freight.file.common.util.AESSecretUtils;
......@@ -8,19 +9,32 @@ import com.esv.freight.file.module.upload.entity.FileMetaEntity;
import com.esv.freight.file.module.upload.form.FileForm;
import com.esv.freight.file.module.upload.service.FileMetaService;
import com.esv.freight.file.module.upload.vo.FileVO;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Base64;
......@@ -37,9 +51,12 @@ public class FileMetaServiceImpl extends ServiceImpl<FileMetaDao, FileMetaEntity
private GridFsTemplate gridFsTemplate;
private MongoDbFactory mongoDbFactory;
@Autowired
public FileMetaServiceImpl(GridFsTemplate gridFsTemplate) {
public FileMetaServiceImpl(GridFsTemplate gridFsTemplate, MongoDbFactory mongoDbFactory) {
this.gridFsTemplate = gridFsTemplate;
this.mongoDbFactory = mongoDbFactory;
}
@Override
......@@ -86,13 +103,90 @@ public class FileMetaServiceImpl extends ServiceImpl<FileMetaDao, FileMetaEntity
}
// 返回数据
String aesId = AESSecretUtils.encryptToStr(fileId + "," + System.currentTimeMillis(), AES_KEY);
String aesId = AESSecretUtils.encryptToStr("esv," + fileId + "," + System.currentTimeMillis(), AES_KEY);
String downloadUrl = FILE_DOWNLOAD_BASE_URL + aesId;
FileVO fileVO = new FileVO(fileId, downloadUrl);
return fileVO;
}
@Override
public void directDownload(String id, HttpServletResponse response) {
// 校验id是否有效
String decryptId;
try {
decryptId = StringUtils.trimToEmpty(AESSecretUtils.decryptToStr(id, AES_KEY));
} catch (Exception e) {
this.downloadError("无效的文件ID", response);
return;
}
String[] ids = decryptId.split(",");
if (3 != ids.length || !"esv".equals(ids[0])) {
this.downloadError("无效的文件ID", response);
return;
}
String fileId = ids[1];
// 获取文件ID
FileMetaEntity queryEntity = new FileMetaEntity();
queryEntity.setFileId(fileId);
QueryWrapper<FileMetaEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.setEntity(queryEntity);
FileMetaEntity fileMetaEntity = this.getOne(queryWrapper);
if (null == fileMetaEntity) {
this.downloadError("无效的文件ID", response);
return;
}
// 获取文件数据
Query query = Query.query(Criteria.where("_id").is(fileId));
GridFSFile gridFSFile = gridFsTemplate.findOne(query);
if (null == gridFSFile) {
this.downloadError("文件数据不存在", response);
return;
} else {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String fileName = gridFSFile.getFilename();
OutputStream outputStream = null;
try {
// 处理中文文件名乱码
if (request.getHeader("User-Agent").toUpperCase().contains("MSIE") ||
request.getHeader("User-Agent").toUpperCase().contains("TRIDENT")
|| request.getHeader("User-Agent").toUpperCase().contains("EDGE")) {
fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
} else {
// 非IE浏览器的处理:
fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
}
response.reset();
response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
response.setCharacterEncoding("UTF-8");
response.setContentLength((int) gridFSFile.getLength());
response.setContentType(this.getFileContentType(fileMetaEntity.getFileType()));
GridFSBucket bucket = GridFSBuckets.create(mongoDbFactory.getDb());
GridFSDownloadStream gridFSDownloadStream = bucket.openDownloadStream(gridFSFile.getObjectId());
GridFsResource gridFsResource = new GridFsResource(gridFSFile, gridFSDownloadStream);
outputStream = response.getOutputStream();
IOUtils.copy(gridFsResource.getInputStream(), outputStream);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
this.downloadError("服务内部错误", response);
} finally {
if (null != outputStream) {
try {
outputStream.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
}
}
/**
* description 删除MongoDB文件
* param [id]
......@@ -137,4 +231,23 @@ public class FileMetaServiceImpl extends ServiceImpl<FileMetaDao, FileMetaEntity
return contentType;
}
/**
* 文件下载错误返回
* @param errorMsg
* @param response
*/
private void downloadError(String errorMsg, HttpServletResponse response) {
try {
response.reset();
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
OutputStream out = response.getOutputStream();
out.write(errorMsg.getBytes("UTF-8"));
out.flush();
out.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
\ No newline at end of file
package com.esv.freight.file.common.util;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @description:
* @project: freight-file-service
* @name: com.esv.freight.file.common.util.AESSecretUtilsTest
* @author: 黄朝斌
* @email: huangchaobin@esvtek.com
* @createTime: 2020/04/14 18:54
* @version:1.0
*/
@SpringBootTest
@Slf4j
public class AESSecretUtilsTest {
@Before
public void before() {
log.info("=================================== Test Start ===================================");
}
@After
public void after() {
log.info("=================================== Test End ===================================");
}
@Test
public void encryptToStr() {
String str = "esv,5e956fd9f99e9e34386fdc7f," + System.currentTimeMillis();
System.out.println(AESSecretUtils.encryptToStr(str, "freight-file-servie-3.1415926535"));
}
}
......@@ -9,6 +9,7 @@ import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
......@@ -16,6 +17,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
import java.io.ByteArrayOutputStream;
......@@ -37,6 +39,7 @@ import java.util.Base64;
@SpringBootTest
@Slf4j
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Transactional
public class UploadControllerTest {
@Autowired
......@@ -56,6 +59,7 @@ public class UploadControllerTest {
}
@Test
@Rollback
public void a1_uploadSingleFile_success_test() throws Exception {
String url = "/upload/single";
JSONObject reqJson = new JSONObject();
......@@ -90,6 +94,7 @@ public class UploadControllerTest {
}
@Test
@Rollback
public void b1_uploadSingleFile_file_type_error_test() throws Exception {
String url = "/upload/single";
JSONObject reqJson = new JSONObject();
......@@ -124,6 +129,7 @@ public class UploadControllerTest {
}
@Test
@Rollback
public void b2_uploadSingleFile_file_size_error_test() throws Exception {
String url = "/upload/single";
JSONObject reqJson = new JSONObject();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment