mirror of
https://github.com/blossom-editor/blossom
synced 2024-11-17 22:48:03 +08:00
查看图片使用 sendfile
This commit is contained in:
parent
9607e16023
commit
5173fd6f26
@ -1,24 +1,31 @@
|
||||
package com.blossom.backend.server.picture;
|
||||
|
||||
import cn.hutool.core.io.FastByteArrayOutputStream;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import com.blossom.backend.base.auth.AuthContext;
|
||||
import com.blossom.backend.base.auth.annotation.AuthIgnore;
|
||||
import com.blossom.backend.server.picture.pojo.PictureEntity;
|
||||
import com.blossom.common.base.pojo.R;
|
||||
import com.blossom.common.base.util.ServletUtil;
|
||||
import com.blossom.common.base.util.spring.AntPathMatcherUtil;
|
||||
import com.blossom.common.iaas.OSManager;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.coobird.thumbnailator.Thumbnails;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* 图片上传下载, 当使用本地图片存储时, 简短的接口名有助于优化文档布局
|
||||
@ -62,78 +69,73 @@ public class PictureBlosController {
|
||||
return R.ok(picture.getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看图片 [OP]
|
||||
*
|
||||
* @param filename 文件名
|
||||
* @param scale 图片分辨率缩放
|
||||
* @param quality 图片质量缩放
|
||||
*/
|
||||
@AuthIgnore
|
||||
@GetMapping("/pic/{filename}/**")
|
||||
public void getFile(
|
||||
@PathVariable String filename,
|
||||
@RequestParam(value = "scale", required = false) Float scale,
|
||||
@RequestParam(value = "quality", required = false) Float quality,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse resp) {
|
||||
if (scale == null) {
|
||||
scale = 1f;
|
||||
}
|
||||
if (quality == null) {
|
||||
quality = 1f;
|
||||
}
|
||||
|
||||
private String getFilename(String filename, HttpServletRequest request) {
|
||||
final String path = request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString();
|
||||
final String bestMatchingPattern = request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString();
|
||||
String arguments = AntPathMatcherUtil.getAntPathMatcher().extractPathWithinPattern(bestMatchingPattern, path);
|
||||
if (!arguments.isEmpty()) {
|
||||
filename = "/" + filename + '/' + arguments;
|
||||
}
|
||||
File file = osManager.get(filename);
|
||||
return filename;
|
||||
}
|
||||
|
||||
InputStream ips = null;
|
||||
FastByteArrayOutputStream ops = null;
|
||||
try {
|
||||
// 图片大于 COMPRESS_MIN_SIZE 大小, 且请求进行压缩时
|
||||
if (file.length() > COMPRESS_MIN_SIZE && (scale < 1f || quality < 1f)) {
|
||||
try {
|
||||
ops = new FastByteArrayOutputStream();
|
||||
Thumbnails.of(file)
|
||||
// 图片大小(长宽)压缩比例 从0-1,1表示原图
|
||||
.scale(scale)
|
||||
// 图片质量压缩比例 从0-1,越接近1质量越好
|
||||
.outputQuality(quality)
|
||||
.toOutputStream(ops);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.toString());
|
||||
ips = new FileInputStream(file);
|
||||
ops = IoUtil.read(ips, true);
|
||||
}
|
||||
} else {
|
||||
ips = new FileInputStream(file);
|
||||
ops = IoUtil.read(ips, true);
|
||||
/**
|
||||
* 查看图片 [OP]
|
||||
*
|
||||
* @param filename 文件名
|
||||
*/
|
||||
@AuthIgnore
|
||||
@GetMapping("/pic/{filename}/**")
|
||||
public ResponseEntity<StreamingResponseBody> getFile(@PathVariable String filename,
|
||||
HttpServletRequest request, HttpServletResponse resp) {
|
||||
filename = getFilename(filename, request);
|
||||
// sendfile 方式下载图片
|
||||
sendfile(filename, resp);
|
||||
return ResponseEntity.ok(null);
|
||||
|
||||
// File file = osManager.get(filename);
|
||||
// resp.setContentType("");
|
||||
// resp.setContentLengthLong(file.length());
|
||||
// try {
|
||||
// InputStream is = new FileInputStream(file);
|
||||
// StreamingResponseBody body = os -> {
|
||||
// int nRead;
|
||||
// byte[] data = new byte[1024];
|
||||
// while ((nRead = is.read(data, 0, data.length)) != -1) {
|
||||
// os.write(data, 0, nRead);
|
||||
// }
|
||||
// };
|
||||
// return ResponseEntity.ok().body(body);
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// return ResponseEntity.ok().body(null);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
private void sendfile(String filename, HttpServletResponse resp) {
|
||||
Path file = Paths.get(filename);
|
||||
|
||||
try (FileChannel fileChannel = FileChannel.open(file); ServletOutputStream os = resp.getOutputStream()) {
|
||||
long size = fileChannel.size();
|
||||
String contentType = Files.probeContentType(file);
|
||||
if (contentType == null) {
|
||||
contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
|
||||
}
|
||||
resp.setContentType(contentType);
|
||||
resp.setContentLengthLong(size);
|
||||
|
||||
resp.setContentType(ServletUtil.getContentTypeImage(filename));
|
||||
OutputStream os = resp.getOutputStream();
|
||||
os.write(ops.toByteArray());
|
||||
os.flush();
|
||||
os.close();
|
||||
long position = 0;
|
||||
WritableByteChannel channel = Channels.newChannel(os);
|
||||
while (size > 0) {
|
||||
long count = fileChannel.transferTo(position, size, channel);
|
||||
if (count > 0) {
|
||||
position += count;
|
||||
size -= count;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (ips != null) {
|
||||
ips.close();
|
||||
}
|
||||
if (ops != null) {
|
||||
ops.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
log.info(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user