【问题标题】:How enforce gzip compression in JAX-RS endpoint / payara-micro response如何在 JAX-RS 端点/payara-micro 响应中强制执行 gzip 压缩
【发布时间】:2020-11-07 20:14:41
【问题描述】:

我在 JAX-RS 端点中以 JSON 响应的形式发送大量数据。

有没有办法将 javax.ws.rs 中的“always-compress”参数设置为端点的注释或在 payara-micro 级别作为参数,以始终压缩响应? p>

当前状态是端点支持uncompressedcompressed(例如curl --compressed)方式提供数据。

@GET
@Path("/big-response")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Provides Json information about some etities")
@ApiResponses(value = {
        @ApiResponse(code = 200, message = "Transfer successful"),
        @ApiResponse(code = 400, message = "Bad request"),
        @ApiResponse(code = 500, message = "Internal server error")})
public void retrieveTheData() {

我希望端点总是以压缩数据响应(内容编码:gzip)。

【问题讨论】:

  • 如果可以将压缩作为注释分别应用于每个 JAX-RS 端点,那就更好了。感谢您的任何建议。
  • 该页面存在类似问题:stackoverflow.com/questions/19765582/… 但不确定是否强制压缩。
  • 这里还有一种实现 WriterInterceptor 的方法:codepedia.org/ama/… 并使用 @Compress 注释 -> 这可能是一个可能的解决方案

标签: jersey compression gzip payara-micro


【解决方案1】:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import javax.ws.rs.NameBinding;

//@Compress annotation is the name binding annotation
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Compress {
}

拦截器

import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.Deflater;
import java.util.zip.GZIPOutputStream;

import javax.enterprise.context.Dependent;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;

import hr.abc.leonus.api.gateway.util.Compress;

@Provider
@Compress
public class GZIPWriterInterceptor implements WriterInterceptor {

    public static final String CONTENT_ENCODING = "Content-Encoding";
    public static final String GZIP = "gzip";

    @Override
    public void aroundWriteTo(WriterInterceptorContext context)
            throws IOException, WebApplicationException {

        MultivaluedMap<String, Object> headers = context.getHeaders();
        headers.add(CONTENT_ENCODING, GZIP);

        final OutputStream outputStream = context.getOutputStream();

        GatewayGZIPOutputStream gzipStream = new GatewayGZIPOutputStream(outputStream);
        gzipStream.setLevel(Deflater.BEST_SPEED);
        context.setOutputStream(gzipStream);
        context.proceed();
    }
}

class GatewayGZIPOutputStreamextends GZIPOutputStream {

    public GatewayGZIPOutputStream(OutputStream out) throws IOException {
        super(out);
    }

    public void setLevel(int level) {
        def.setLevel(level);
    }
}

在端点上的使用

@Compress
@GET
@Path("/big-response")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Provides Json information about some etities")
@ApiResponses(value = {
        @ApiResponse(code = 200, message = "Transfer successful"),
        @ApiResponse(code = 400, message = "Bad request"),
        @ApiResponse(code = 500, message = "Internal server error")})
public void retrieveTheData() {
}

您可以通过设置级别来调整 GatewayGZIPOutputStream 对象中的压缩级别。我正在使用最低速度以获得最佳速度。 @Compress 注解可以用在方法上,也可以用在类内每个方法的资源类上。

【讨论】:

    猜你喜欢
    • 2017-06-20
    • 2014-05-31
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多