版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
我先说下背景,我们这边有个平台组,文件服务就是平台组的服务。文件服务包括文件上传下载功能,服务的文件是保存在mongodb中。(注:平台组的代码很难改动,我只有自己想办法解决问题!)
实现图片预览的思路是这样的:
- Feign调用文件服务的,获取feign.Response 对象。
- 将获取Feign.Response对象的输出流,封装一层,返回给前台。
- 前台通过接收到二进制文件通过Blob转化,就可直接预览图片。
具体的个步骤的关键代码如下:
1. 文件服务文件下载接口,代码如下:
@RequestMapping(value = "/downloadFile")
public void downloadFile(@RequestParam(name = "file_id") String fileId, HttpServletRequest request, HttpServletResponse response) throws Exception {
Query query = Query.query(Criteria.where("_id").is(fileId));
// 查询单个文件
GridFSDBFile gfsfile = gridFsTemplate.findOne(query);
if (gfsfile == null) {
return;
}
String fileName = gfsfile.getFilename().replace(",", "");
//处理中文文件名乱码
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.setContentType(gfsfile.getContentType());
response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
gfsfile.writeTo(response.getOutputStream());
}
2.调用方图片预览的代码如下:
@GetMapping("/preview/{fileId}")
public Response<byte[]> imagePreview(@PathVariable String fileId) throws Exception{
fiegn.Response response = fileClientService.downloadFile(fileId); // feign调用获取下载接口的响应
Response.Body body = response.body();
HttpHeaders heads = new HttpHeaders();
heads.setContentType(MediaType.valueOf(MediaType.IMAGE_JPEG_VALUE));
return new Response<byte[]>(IoUtil.readBytes(body.asInputStream()),heads, HttpStatus.OK);
}
3.前台代码如下:
var imageType = xhr.getResponseHeader("Content-Type");
var blob = new Blob([xhr.response], { type: imageType });
var imageUrl = (window.URL || window.webkitURL).createObjectURL(blob);
$('#image').attr("src", imageUrl);