diff --git a/blossom-backend/backend/src/main/java/com/blossom/backend/server/picture/PictureBlosController.java b/blossom-backend/backend/src/main/java/com/blossom/backend/server/picture/PictureBlosController.java index 7ce4cb0..d762bca 100644 --- a/blossom-backend/backend/src/main/java/com/blossom/backend/server/picture/PictureBlosController.java +++ b/blossom-backend/backend/src/main/java/com/blossom/backend/server/picture/PictureBlosController.java @@ -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 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()); } }