From 29b3e75c9fc730817781f97dfa5536cee6e07f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johnny=20Miller=20=28=E9=94=BA=E4=BF=8A=29?= Date: Fri, 3 Sep 2021 20:33:58 +0800 Subject: [PATCH] feat($oss-center): add new API for resource response --- .../controller/ReadResourceController.java | 9 +++++- .../read/service/ReadResourceService.java | 12 +++++++- .../service/impl/ReadResourceServiceImpl.java | 29 +++++++++++++++++-- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/controller/ReadResourceController.java b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/controller/ReadResourceController.java index 86991c4a..abf7bdce 100644 --- a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/controller/ReadResourceController.java +++ b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/controller/ReadResourceController.java @@ -29,8 +29,15 @@ public class ReadResourceController { private final ReadResourceService readResourceService; + @GetMapping("/{bucket}/{object}") + @ApiOperation(value = "Get single resource", notes = "Get single resource (small-size file)") + public ResponseEntity asyncGetSingleResource(@PathVariable String bucket, + @PathVariable String object) { + return this.readResourceService.asyncGetSingleResource(bucket, object); + } + @GetMapping("/stream/{bucket}/{object}") - @ApiOperation(value = "Stream single resource", notes = "Stream single resource") + @ApiOperation(value = "Stream single resource", notes = "Stream single resource (large-size file)") public ResponseEntity asyncStreamSingleResource(@PathVariable String bucket, @PathVariable String object, @RequestHeader(name = HttpHeaders.RANGE, diff --git a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/ReadResourceService.java b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/ReadResourceService.java index 880252e3..0237b0d6 100644 --- a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/ReadResourceService.java +++ b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/ReadResourceService.java @@ -25,7 +25,17 @@ public interface ReadResourceService { DataSize LARGE_CHUNK_SIZE = DataSize.ofMegabytes(8); /** - * Async stream single resource response entity. + * Get single resource, especially pictures, or other small size file. + * + * @param bucket the bucket + * @param object the object + * @return the response entity + */ + ResponseEntity asyncGetSingleResource(String bucket, String object); + + /** + * Stream single resource, more efficiency if the resource is large file, which will be streamed by range. + * Responsive streaming * * @param bucket the bucket * @param object the object diff --git a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/impl/ReadResourceServiceImpl.java b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/impl/ReadResourceServiceImpl.java index 80688aee..e5d7ad09 100644 --- a/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/impl/ReadResourceServiceImpl.java +++ b/oss-center/src/main/java/com/jmsoftware/maf/osscenter/read/service/impl/ReadResourceServiceImpl.java @@ -29,9 +29,32 @@ @Service @RequiredArgsConstructor public class ReadResourceServiceImpl implements ReadResourceService { + private static final String ACCEPT_RANGES_VALUE = "bytes"; private final MinioHelper minioHelper; @Override + @SuppressWarnings("DuplicatedCode") + public ResponseEntity asyncGetSingleResource(String bucket, String object) { + StatObjectResponse statObjectResponse; + try { + statObjectResponse = this.minioHelper.statObject(bucket, object); + } catch (Exception e) { + log.error("Exception occurred when looking for object. Exception message: {}", e.getMessage()); + return ResponseEntity.notFound().build(); + } + val getObjectResponse = this.minioHelper.getObject(bucket, object); + return ResponseEntity.ok() + .header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_VALUE) + .contentLength(statObjectResponse.size()) + .contentType(MediaType.parseMediaType(statObjectResponse.contentType())) + .body(outputStream -> { + NioUtil.copyByNIO(getObjectResponse, outputStream, NioUtil.DEFAULT_BUFFER_SIZE, null); + IoUtil.close(getObjectResponse); + }); + } + + @Override + @SuppressWarnings("DuplicatedCode") public ResponseEntity asyncStreamSingleResource(@NotBlank String bucket, @NotBlank String object, @Nullable String range) { @@ -46,7 +69,7 @@ public ResponseEntity asyncStreamSingleResource(@NotBlank if (CollUtil.isEmpty(httpRanges)) { val getObjectResponse = this.minioHelper.getObject(bucket, object, 0, TINY_CHUNK_SIZE.toBytes()); return ResponseEntity.ok() - .header(HttpHeaders.ACCEPT_RANGES, "bytes") + .header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_VALUE) .contentLength(statObjectResponse.size()) .contentType(MediaType.parseMediaType(statObjectResponse.contentType())) .body(outputStream -> { @@ -70,7 +93,7 @@ public ResponseEntity asyncDownloadSingleResource(@NotBla } val getObjectResponse = this.minioHelper.getObject(bucket, object); return ResponseEntity.ok() - .header(HttpHeaders.ACCEPT_RANGES, "bytes") + .header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_VALUE) .header(HttpHeaders.CONTENT_DISPOSITION, ContentDisposition.builder("attachment").filename(object).build().toString()) .contentLength(statObjectResponse.size()) @@ -98,7 +121,7 @@ private ResponseEntity asyncGetResourceRegion(String buck end = Math.min(end, resourceLength - 1); val rangeLength = end - start + 1; return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT) - .header(HttpHeaders.ACCEPT_RANGES, "bytes") + .header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_VALUE) .header(HttpHeaders.CONTENT_RANGE, String.format("bytes %d-%d/%d", start, end, resourceLength)) .contentLength(rangeLength) .contentType(MediaType.parseMediaType(statObjectResponse.contentType()))