Add gzip compression for load dashboard and download svg images methods.
This commit is contained in:
parent
ab2e788057
commit
749df3f212
@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import jakarta.mail.MessagingException;
|
import jakarta.mail.MessagingException;
|
||||||
|
import jakarta.servlet.ServletOutputStream;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.validation.ConstraintViolation;
|
import jakarta.validation.ConstraintViolation;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -28,6 +29,7 @@ import org.slf4j.Logger;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -182,7 +184,9 @@ import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
|
|||||||
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
|
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
|
||||||
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -194,6 +198,7 @@ import java.util.function.BiConsumer;
|
|||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
import static org.thingsboard.server.common.data.StringUtils.isNotEmpty;
|
import static org.thingsboard.server.common.data.StringUtils.isNotEmpty;
|
||||||
import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD;
|
import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD;
|
||||||
@ -1008,6 +1013,22 @@ public abstract class BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void compressResponseWithGzipIFAccepted(String acceptEncodingHeader, HttpServletResponse response, byte[] content) throws IOException {
|
||||||
|
if (StringUtils.isNotEmpty(acceptEncodingHeader) && acceptEncodingHeader.contains("gzip")) {
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_ENCODING, "gzip");
|
||||||
|
response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
|
||||||
|
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(response.getOutputStream())) {
|
||||||
|
gzipOutputStream.write(content);
|
||||||
|
gzipOutputStream.finish();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try (ServletOutputStream outputStream = response.getOutputStream()) {
|
||||||
|
outputStream.write(content);
|
||||||
|
outputStream.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected <T> ResponseEntity<T> response(HttpStatus status) {
|
protected <T> ResponseEntity<T> response(HttpStatus status) {
|
||||||
return ResponseEntity.status(status).build();
|
return ResponseEntity.status(status).build();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,8 +22,10 @@ import io.swagger.v3.oas.annotations.media.Content;
|
|||||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
@ -31,6 +33,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
@ -67,6 +70,7 @@ import java.util.Set;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID;
|
import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID;
|
||||||
import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
|
import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION;
|
||||||
import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_ID_PARAM_DESCRIPTION;
|
import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_ID_PARAM_DESCRIPTION;
|
||||||
@ -149,17 +153,20 @@ public class DashboardController extends BaseController {
|
|||||||
)
|
)
|
||||||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
|
||||||
@GetMapping(value = "/dashboard/{dashboardId}")
|
@GetMapping(value = "/dashboard/{dashboardId}")
|
||||||
public Dashboard getDashboardById(@Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION)
|
public void getDashboardById(@Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION)
|
||||||
@PathVariable(DASHBOARD_ID) String strDashboardId,
|
@PathVariable(DASHBOARD_ID) String strDashboardId,
|
||||||
@Parameter(description = INCLUDE_RESOURCES_DESCRIPTION)
|
@Parameter(description = INCLUDE_RESOURCES_DESCRIPTION)
|
||||||
@RequestParam(value = INCLUDE_RESOURCES, required = false) boolean includeResources) throws ThingsboardException {
|
@RequestParam(value = INCLUDE_RESOURCES, required = false) boolean includeResources,
|
||||||
|
@RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader,
|
||||||
|
HttpServletResponse response) throws Exception {
|
||||||
checkParameter(DASHBOARD_ID, strDashboardId);
|
checkParameter(DASHBOARD_ID, strDashboardId);
|
||||||
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
|
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
|
||||||
Dashboard dashboard = checkDashboardId(dashboardId, Operation.READ);
|
Dashboard dashboard = checkDashboardId(dashboardId, Operation.READ);
|
||||||
if (includeResources) {
|
if (includeResources) {
|
||||||
dashboard.setResources(tbResourceService.exportResources(dashboard, getCurrentUser()));
|
dashboard.setResources(tbResourceService.exportResources(dashboard, getCurrentUser()));
|
||||||
}
|
}
|
||||||
return dashboard;
|
response.setContentType(APPLICATION_JSON_VALUE);
|
||||||
|
compressResponseWithGzipIFAccepted(acceptEncodingHeader, response, JacksonUtil.writeValueAsBytes(dashboard));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "Create Or Update Dashboard (saveDashboard)",
|
@ApiOperation(value = "Create Or Update Dashboard (saveDashboard)",
|
||||||
@ -171,11 +178,15 @@ public class DashboardController extends BaseController {
|
|||||||
TENANT_AUTHORITY_PARAGRAPH)
|
TENANT_AUTHORITY_PARAGRAPH)
|
||||||
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
||||||
@PostMapping(value = "/dashboard")
|
@PostMapping(value = "/dashboard")
|
||||||
public Dashboard saveDashboard(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "A JSON value representing the dashboard.")
|
public void saveDashboard(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "A JSON value representing the dashboard.")
|
||||||
@RequestBody Dashboard dashboard) throws Exception {
|
@RequestBody Dashboard dashboard,
|
||||||
|
@RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader,
|
||||||
|
HttpServletResponse response) throws Exception {
|
||||||
dashboard.setTenantId(getTenantId());
|
dashboard.setTenantId(getTenantId());
|
||||||
checkEntity(dashboard.getId(), dashboard, Resource.DASHBOARD);
|
checkEntity(dashboard.getId(), dashboard, Resource.DASHBOARD);
|
||||||
return tbDashboardService.save(dashboard, getCurrentUser());
|
var savedDashboard = tbDashboardService.save(dashboard, getCurrentUser());
|
||||||
|
response.setContentType(APPLICATION_JSON_VALUE);
|
||||||
|
compressResponseWithGzipIFAccepted(acceptEncodingHeader, response, JacksonUtil.writeValueAsBytes(savedDashboard));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "Delete the Dashboard (deleteDashboard)",
|
@ApiOperation(value = "Delete the Dashboard (deleteDashboard)",
|
||||||
@ -408,12 +419,13 @@ public class DashboardController extends BaseController {
|
|||||||
"If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. "
|
"If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. "
|
||||||
+ DASHBOARD_DEFINITION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
|
+ DASHBOARD_DEFINITION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
|
||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
|
||||||
@RequestMapping(value = "/dashboard/home", method = RequestMethod.GET)
|
@GetMapping(value = "/dashboard/home")
|
||||||
@ResponseBody
|
public void getHomeDashboard(@RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader,
|
||||||
public HomeDashboard getHomeDashboard() throws ThingsboardException {
|
HttpServletResponse response) throws Exception {
|
||||||
SecurityUser securityUser = getCurrentUser();
|
SecurityUser securityUser = getCurrentUser();
|
||||||
|
response.setContentType(APPLICATION_JSON_VALUE);
|
||||||
if (securityUser.isSystemAdmin()) {
|
if (securityUser.isSystemAdmin()) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
User user = userService.findUserById(securityUser.getTenantId(), securityUser.getId());
|
User user = userService.findUserById(securityUser.getTenantId(), securityUser.getId());
|
||||||
JsonNode additionalInfo = user.getAdditionalInfo();
|
JsonNode additionalInfo = user.getAdditionalInfo();
|
||||||
@ -431,7 +443,9 @@ public class DashboardController extends BaseController {
|
|||||||
homeDashboard = extractHomeDashboardFromAdditionalInfo(additionalInfo);
|
homeDashboard = extractHomeDashboardFromAdditionalInfo(additionalInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return homeDashboard;
|
if (homeDashboard != null) {
|
||||||
|
compressResponseWithGzipIFAccepted(acceptEncodingHeader, response, JacksonUtil.writeValueAsBytes(homeDashboard));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "Get Home Dashboard Info (getHomeDashboardInfo)",
|
@ApiOperation(value = "Get Home Dashboard Info (getHomeDashboardInfo)",
|
||||||
|
|||||||
@ -61,7 +61,9 @@ import org.thingsboard.server.service.security.model.SecurityUser;
|
|||||||
import org.thingsboard.server.service.security.permission.Operation;
|
import org.thingsboard.server.service.security.permission.Operation;
|
||||||
import org.thingsboard.server.service.security.permission.Resource;
|
import org.thingsboard.server.service.security.permission.Resource;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
|
||||||
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
|
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
|
||||||
@ -70,6 +72,7 @@ import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_INC
|
|||||||
import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_TEXT_SEARCH_DESCRIPTION;
|
import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_TEXT_SEARCH_DESCRIPTION;
|
||||||
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
|
||||||
import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
|
import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
|
||||||
|
import static org.thingsboard.server.dao.util.ImageUtils.mediaTypeToFileExtension;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@ -179,15 +182,17 @@ public class ImageController extends BaseController {
|
|||||||
@PathVariable String type,
|
@PathVariable String type,
|
||||||
@Parameter(description = IMAGE_KEY_PARAM_DESCRIPTION, required = true)
|
@Parameter(description = IMAGE_KEY_PARAM_DESCRIPTION, required = true)
|
||||||
@PathVariable String key,
|
@PathVariable String key,
|
||||||
@RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws Exception {
|
@RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag,
|
||||||
return downloadIfChanged(type, key, etag, false);
|
@RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader) throws Exception {
|
||||||
|
return downloadIfChanged(type, key, etag, acceptEncodingHeader, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/api/images/public/{publicResourceKey}", produces = "image/*")
|
@GetMapping(value = "/api/images/public/{publicResourceKey}", produces = "image/*")
|
||||||
public ResponseEntity<ByteArrayResource> downloadPublicImage(@PathVariable String publicResourceKey,
|
public ResponseEntity<ByteArrayResource> downloadPublicImage(@PathVariable String publicResourceKey,
|
||||||
@RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws Exception {
|
@RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag,
|
||||||
|
@RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader) throws Exception {
|
||||||
ImageCacheKey cacheKey = ImageCacheKey.forPublicImage(publicResourceKey);
|
ImageCacheKey cacheKey = ImageCacheKey.forPublicImage(publicResourceKey);
|
||||||
return downloadIfChanged(cacheKey, etag, () -> imageService.getPublicImageInfoByKey(publicResourceKey));
|
return downloadIfChanged(cacheKey, etag, acceptEncodingHeader, () -> imageService.getPublicImageInfoByKey(publicResourceKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
||||||
@ -213,8 +218,9 @@ public class ImageController extends BaseController {
|
|||||||
@PathVariable String type,
|
@PathVariable String type,
|
||||||
@Parameter(description = IMAGE_KEY_PARAM_DESCRIPTION, required = true)
|
@Parameter(description = IMAGE_KEY_PARAM_DESCRIPTION, required = true)
|
||||||
@PathVariable String key,
|
@PathVariable String key,
|
||||||
@RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws Exception {
|
@RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag,
|
||||||
return downloadIfChanged(type, key, etag, true);
|
@RequestHeader(name = HttpHeaders.ACCEPT_ENCODING, required = false) String acceptEncodingHeader) throws Exception {
|
||||||
|
return downloadIfChanged(type, key, etag, acceptEncodingHeader, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
||||||
@ -268,12 +274,12 @@ public class ImageController extends BaseController {
|
|||||||
return (result.isSuccess() ? ResponseEntity.ok() : ResponseEntity.badRequest()).body(result);
|
return (result.isSuccess() ? ResponseEntity.ok() : ResponseEntity.badRequest()).body(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<ByteArrayResource> downloadIfChanged(String type, String key, String etag, boolean preview) throws Exception {
|
private ResponseEntity<ByteArrayResource> downloadIfChanged(String type, String key, String etag, String acceptEncodingHeader, boolean preview) throws Exception {
|
||||||
ImageCacheKey cacheKey = ImageCacheKey.forImage(getTenantId(type), key, preview);
|
ImageCacheKey cacheKey = ImageCacheKey.forImage(getTenantId(type), key, preview);
|
||||||
return downloadIfChanged(cacheKey, etag, () -> checkImageInfo(type, key, Operation.READ));
|
return downloadIfChanged(cacheKey, etag, acceptEncodingHeader, () -> checkImageInfo(type, key, Operation.READ));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<ByteArrayResource> downloadIfChanged(ImageCacheKey cacheKey, String etag, ThrowingSupplier<TbResourceInfo> imageInfoSupplier) throws Exception {
|
private ResponseEntity<ByteArrayResource> downloadIfChanged(ImageCacheKey cacheKey, String etag, String acceptEncodingHeader, ThrowingSupplier<TbResourceInfo> imageInfoSupplier) throws Exception {
|
||||||
if (StringUtils.isNotEmpty(etag)) {
|
if (StringUtils.isNotEmpty(etag)) {
|
||||||
etag = StringUtils.remove(etag, '\"'); // etag is wrapped in double quotes due to HTTP specification
|
etag = StringUtils.remove(etag, '\"'); // etag is wrapped in double quotes due to HTTP specification
|
||||||
if (etag.equals(tbImageService.getETag(cacheKey))) {
|
if (etag.equals(tbImageService.getETag(cacheKey))) {
|
||||||
@ -294,7 +300,6 @@ public class ImageController extends BaseController {
|
|||||||
tbImageService.putETag(cacheKey, descriptor.getEtag());
|
tbImageService.putETag(cacheKey, descriptor.getEtag());
|
||||||
var result = ResponseEntity.ok()
|
var result = ResponseEntity.ok()
|
||||||
.header("Content-Type", descriptor.getMediaType())
|
.header("Content-Type", descriptor.getMediaType())
|
||||||
.contentLength(data.length)
|
|
||||||
.eTag(descriptor.getEtag());
|
.eTag(descriptor.getEtag());
|
||||||
if (!cacheKey.isPublic()) {
|
if (!cacheKey.isPublic()) {
|
||||||
result
|
result
|
||||||
@ -308,7 +313,19 @@ public class ImageController extends BaseController {
|
|||||||
} else {
|
} else {
|
||||||
result.cacheControl(CacheControl.noCache());
|
result.cacheControl(CacheControl.noCache());
|
||||||
}
|
}
|
||||||
return result.body(new ByteArrayResource(data));
|
var responseData = data;
|
||||||
|
if (mediaTypeToFileExtension(descriptor.getMediaType()).equals("svg") &&
|
||||||
|
StringUtils.isNotEmpty(acceptEncodingHeader) && acceptEncodingHeader.contains("gzip")) {
|
||||||
|
result.header(HttpHeaders.CONTENT_ENCODING, "gzip");
|
||||||
|
var outputStream = new ByteArrayOutputStream();
|
||||||
|
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream)) {
|
||||||
|
gzipOutputStream.write(data);
|
||||||
|
gzipOutputStream.finish();
|
||||||
|
}
|
||||||
|
responseData = outputStream.toByteArray();
|
||||||
|
}
|
||||||
|
result.contentLength(responseData.length);
|
||||||
|
return result.body(new ByteArrayResource(responseData));
|
||||||
}
|
}
|
||||||
|
|
||||||
private TbResourceInfo checkImageInfo(String imageType, String key, Operation operation) throws ThingsboardException {
|
private TbResourceInfo checkImageInfo(String imageType, String key, Operation operation) throws ThingsboardException {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user