欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

压缩从后端到前端的返回数据的注释方式--方案

最编程 2024-10-19 17:26:27
...

注解@Gzip压缩后端返回数据(前端不用做任何处理)


import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.Objects;
import java.util.zip.GZIPOutputStream;

@Aspect
@Slf4j
@Component
public class GzipAspect {

    @Pointcut("@annotation(com.xxx.xxx.xxx.annotation.gzip.Gzip)")
    public void gzipAnnotation() {}

    @AfterReturning(pointcut = "gzipAnnotation()", returning = "result")
    public void applyGzipCompression(JoinPoint joinPoint, Object result) {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse();
        if (Objects.isNull(response)) return;
        try {
            ObjectMapper mapper = new ObjectMapper();
            byte[] data = mapper.writeValueAsBytes(result);
            // 当返回体大于2048KB开启Gzip
            if (data.length < 2048 * 1024) {
                return;
            }
            response.setHeader("Content-Encoding", "gzip");
            response.setHeader("Vary", "Accept-Encoding");
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
            gzipOutputStream.write(data);
            gzipOutputStream.close();
            byte[] compressedData = byteArrayOutputStream.toByteArray();
            response.setContentLength(compressedData.length);
            ServletOutputStream servletOutputStream = response.getOutputStream();
            servletOutputStream.write(compressedData);
            servletOutputStream.flush();
            servletOutputStream.close();
        } catch (Throwable e) {
            log.error("开启Gzip返回失败");
            log.error(e.getMessage());
        }
    }
}

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 对标注有@Gzip的接口进行gzip算法压缩
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Gzip {
}

使用:直接将注解@Gzip加在对应接口的controller方法上面

推荐阅读