gpt4 book ai didi

java - 如何在 JAX-RS 中提供已经压缩的内容?

转载 作者:行者123 更新时间:2023-11-30 08:53:49 25 4
gpt4 key购买 nike

我正在使用 Resteasy 开发一个小型 JAX-RS 应用程序。我希望应用程序为 Javascript 和 CSS 文件等提供一些静态内容,并且我想利用打包在 webjars.org 的 jars 中的资源的已 gzip 版本。 .因此,我需要处理 Accept-Encoding header 并检查 .gz 是否存在(或不存在)。

到目前为止,我所拥有的是:

@Path("res/{path:.*}")
@GET
public Response webjars(@PathParam("path") String path, @HeaderParam("Accept-Encoding") String acceptEncoding) {

// Guesses MIME type from the path extension elsewhere.
String mime = mimes.getContentType(path);

if (acceptEncoding.contains("gzip")) {
InputStream is = getClass().getResourceAsStream("/META-INF/resources/webjars/" + path + ".gz");
if (is != null)
return Response.ok().type(mime).encoding("gzip").entity(is).build();
}

InputStream is = getClass().getResourceAsStream("/META-INF/resources/webjars/" + path);
if (is != null)
return Response.ok().type(mime).entity(is).build();

return Response.status(Status.NOT_FOUND).build();
}

但它不起作用。提供的内容完全被破坏了。到目前为止,我发现了一个再次压缩流的组件:org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor因为我手动填充了Content-Encoding header (使用ResponseBuilder.encoding方法)。

这对我来说像是一个错误,因为显然无法共享已经 gzip 压缩的流。但是,这可以使用 JAX-RS 实现吗?这是 Resteasy 的错误吗?

我可以想出多种方法在 Resteasy 外部实现同样的事情,比如映射 webjars.org servlet(我不在 Servlet API 3.0 环境中,所以我没有 META-INF/resources/ 自动类路径映射)。尽管如此,我的问题仍然存在。它适用于其他几个场景。

更新:

为了记录,我已经填写了问题 RESTEASY-1170 .

最佳答案

这是我上述评论的示例实现。

The point I'm getting at is that if you don't want it to be handle by the current interceptor, don't set the header, create an Interceptor that will be name binded, with your own annotation, and set the priority to one lower than the one you want to avoid, then set the header in your Interceptor...

@AlreadyGzipped

@NameBinding
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AlreadyGzipped {}

WriterInterceptor .注意 @PriorityGZIPEncodingInterceptor 使用 Priorities.ENTITY_CODER

@Provider
@AlreadyGzipped
@Priority(Priorities.ENTITY_CODER + 1000)
public class AlreadyGzippedWriterInterceptor implements WriterInterceptor {
@Context HttpHeaders headers;

@Override
public void aroundWriteTo(WriterInterceptorContext wic) throws IOException,
WebApplicationException {
String header = headers.getHeaderString("Accept-Encoding");
if (null != header && header.equalsIgnoreCase("gzip")) {
wic.getHeaders().putSingle("Content-Encoding", "gzip");
}
wic.proceed();
}
}

测试资源

@Path("resource")
public class AlreadyGzippedResoure {

@GET
@AlreadyGzipped
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getAlreadGzipped() throws Exception {
InputStream is = getClass().getResourceAsStream("/stackoverflow.png.gz");
return Response.ok(is).build();
}
}

测试

public class Main {
public static void main(String[] args) throws Exception {
Client client = ClientBuilder.newClient();
String url = "http://localhost:8080/api/resource";

Response response = client.target(url).request().acceptEncoding("gzip").get();
Image image = ImageIO.read(response.readEntity(InputStream.class));
JOptionPane.showMessageDialog(null,new JLabel(new ImageIcon(image)));
}
}

结果

enter image description here

关于java - 如何在 JAX-RS 中提供已经压缩的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29653641/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com