在某些情况下,您的REST api会提供非常长的响应,我们都知道移动设备/网络上的传输速度和带宽仍然非常重要。 我认为这是开发支持移动应用程序的REST api时需要解决的第一个性能优化点。 你猜怎么了? 因为响应是文本,所以我们可以压缩它们。 借助当今智能手机和平板电脑的强大功能,在客户端上解压缩它们并不是什么大不了的事。因此,在本文中,我将介绍如何使用泽西岛(Jersey)在Java中构建压缩REST API响应的方法。是JAX-RS参考实现(以及更多)…

1.球衣过滤器和拦截器

好吧,得益于Jersey强大的过滤器和拦截器功能,实现起来相当容易。 过滤器主要用于操纵请求和响应参数,例如HTTP头,URI和/或HTTP方法,而拦截器则用于通过操纵实体输入/输出流来操纵实体。

您已经在我的帖子中看到了过滤器的功能:

  • 如何使用Jersey来在Java的服务器端添加CORS支持 ,在此我展示了如何CORS启用REST API
  • 如何使用SLF4J和Logback登录Spring ,在这里我展示了如何记录来自REST API的请求和响应

但要进行压缩,将使用GZip WriterInterceptor 。 Writer拦截器用于将实体写入“线路”的情况,在这种情况下,在服务器端,这意味着写出响应实体时。

GZip作家拦截器

因此,让我们看一下我们的GZip Writer拦截器:

GZip作家拦截器

package org.codingpedia.demo.rest.interceptors;import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;@Provider
@Compress
public class GZIPWriterInterceptor implements WriterInterceptor {@Overridepublic void aroundWriteTo(WriterInterceptorContext context)throws IOException, WebApplicationException {MultivaluedMap<String,Object> headers = context.getHeaders();headers.add("Content-Encoding", "gzip");final OutputStream outputStream = context.getOutputStream();context.setOutputStream(new GZIPOutputStream(outputStream));context.proceed();}
}

注意:

  • 它实现了WriterInterceptor ,它是消息正文WriterInterceptor器拦截器的接口,该拦截器包装了对javax.ws.rs.ext.MessageBodyWriter.writeTo调用。
  • 实现WriterInterceptor合同的提供程序必须在JAX-RS运行时中以编程方式注册,或者必须使用@Provider批注进行注释,以在提供程序扫描阶段由JAX-RS运行时自动发现。
  • @Compress是名称绑定批注,我们将在下一段中对其进行详细讨论
  • “拦截器从WriterInterceptorContext获取输出流,并设置一个新流,它是原始输出流的GZIP包装器。 执行完所有拦截器后,最后设置为WriterInterceptorContext的输出流将用于实体的序列化。 在上面的示例中,实体字节将被写入GZIPOutputStream,它将压缩流数据并将其写入原始输出流。 原始流始终是将数据写入“电线”的流。 在服务器上使用拦截器时,原始输出流是将数据写入基础服务器容器流的流,该服务器容器流将响应发送到客户端。 [2]
  • “ WriteTo()的重写方法将WriterInterceptorContext作为参数。 此上下文包含标头参数,请求属性,实体,实体流和其他属性的获取器和设置器。” [2]; 压缩响应时,应将“ Content-Encoding”标头设置为“ gzip”

压缩注释

过滤器和拦截器可以绑定名称 。 名称绑定是一个概念,它允许对JAX-RS运行时说,仅针对特定的资源方法才执行特定的过滤器或拦截器。 当过滤器或拦截器仅限于特定的资源方法时,我们说它是名称绑定的 。 没有这种限制的过滤器和拦截器称为global 。 在我们的案例中,我们构建了@Compress批注:

压缩注释

package org.codingpedia.demo.rest.interceptors;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 {}

并用它来标记应该压缩的资源上的方法( 例如,使用PodcastsResource获取所有播PodcastsResource ):

@Compress资源方法上的注释用法

@Component
@Path("/podcasts")
public class PodcastsResource {@Autowiredprivate PodcastService podcastService;.........................../** *********************************** READ ************************************//*** Returns all resources (podcasts) from the database* * @return* @throws IOException* @throws JsonMappingException* @throws JsonGenerationException* @throws AppException*/@GET@Compress@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })public List<Podcast> getPodcasts(@QueryParam("orderByInsertionDate") String orderByInsertionDate,@QueryParam("numberDaysToLookBack") Integer numberDaysToLookBack)throws IOException,   AppException {List<Podcast> podcasts = podcastService.getPodcasts(orderByInsertionDate, numberDaysToLookBack);return podcasts;}...........................
}

2.测试

SOAPui

好吧,如果您正在使用SOAPui进行测试,则可以针对PodcastsResource发出以下请求。

请求:

要求范例

GET http://localhost:8888/demo-rest-jersey-spring/podcasts/?orderByInsertionDate=DESC HTTP/1.1
Accept-Encoding: gzip,deflate
Accept: application/json, application/xml
Host: localhost:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

响应:

GZipped json响应,由SOAPui自动解压缩

HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: gzip
Content-Length: 409
Server: Jetty(9.0.7.v20131107)[{"id": 2,"title": "Quarks & Co - zum Mitnehmen","linkOnPodcastpedia": "http://www.podcastpedia.org/quarks","feed": "http://podcast.wdr.de/quarks.xml","description": "Quarks & Co: Das Wissenschaftsmagazin","insertionDate": "2014-10-29T10:46:13.00+0100"},{"id": 1,"title": "- The Naked Scientists Podcast - Stripping Down Science","linkOnPodcastpedia": "http://www.podcastpedia.org/podcasts/792/-The-Naked-Scientists-Podcast-Stripping-Down-Science","feed": "feed_placeholder","description": "The Naked Scientists flagship science show brings you a lighthearted look at the latest scientific breakthroughs, interviews with the world top scientists, answers to your science questions and science experiments to try at home.","insertionDate": "2014-10-29T10:46:02.00+0100"}
]

SOAPui可以识别Content-Type: gzip标头(已添加到GZIPWriterInterceptor并自动解压缩响应并将其显示为人眼可读。

好吧,就是这样。 您已经了解到Jersey如何直接压缩REST api响应。

提示:如果您真的想学习如何在Java中设计和实现REST API,请阅读以下教程–借助Jersey和Spring在Java中进行REST API设计和实现

翻译自: https://www.javacodegeeks.com/2014/11/how-to-compress-responses-in-java-rest-api-with-gzip-and-jersey.html

如何使用GZip和Jersey压缩Java REST API中的响应相关推荐

  1. api 数据gzip压缩_如何使用GZip和Jersey压缩Java REST API中的响应

    api 数据gzip压缩 在某些情况下,您的REST api会提供非常长的响应,我们都知道移动设备/网络上的传输速度和带宽仍然非常重要. 我认为这是开发支持移动应用程序的REST api时需要解决的第 ...

  2. 使用GZIP和Zip压缩Java数据流

    转载自   使用GZIP和Zip压缩Java数据流 本文通过对数据压缩算法的简要介绍,然后以详细的示例演示了利用java.util.zip包实现数据的压缩与解压,并扩展到在网络传输方面如何应用java ...

  3. Java Persistence API中的FetchType LAZY和EAGER之间的区别?

    我是Java Persistence API和Hibernate的新手. Java Persistence API中的FetchType.LAZY和FetchType.EAGER什么区别? #1楼 我 ...

  4. Java数据结构一 —— Java Collections API中的表

    1.Collection接口 位于java.util包中,以下是重要的部分. 1 public interface Collection<AnyType> extends Iterable ...

  5. Java基础学习总结(67)——Java接口API中使用数组的缺陷

    如果你发现在一个接口使用有如下定义方法: public String[] getParameters(); 那么你应该认真反思.数组不仅仅老式,而且我们有合理的理由避免暴露它们.在这篇文章中,我将试图 ...

  6. Java Servlet API中的forward()方法和redirect()方法的区别

    forward():是容器中控制权的转让,在客户端浏览器地址栏不会显示转向后的地址.forward会将  request  state.bean.等信息带到下一个jsp页面:使用getAttribut ...

  7. stream去重_使用Java Stream API中DistinctBy删除重复数据

    Stream API提供distinct()方法,该方法基于数据Object类的equals()方法返回列表的不同元素.下面先做一个数据Object类,用来发现重复数据: public class L ...

  8. react api_使用Java EE 8中的React式API加速服务

    react api 服务通常可以通过异步处理进行优化,即使不改变其对外界的行为. 某些服务效率不高的原因是,它们需要等待其他服务提供结果才能继续下去. 让我们看一下如何在不等待外部REST服务的情况下 ...

  9. 使用Java EE 8中的反应式API加速服务

    服务通常可以通过异步处理进行优化,即使不改变其对外界的行为. 某些服务效率不高的原因是,它们需要等待其他服务提供结果才能继续下去. 让我们看一下如何在不等待外部REST服务的情况下调用它们,并独立进行 ...

最新文章

  1. 简单有趣的matlab小程序_超实用有趣的五个小程序推荐
  2. python连接access数据库查询并打印出来_Python连接Access和读取Access数据库的例子
  3. 10.图的深度优先遍历序列是否唯一?为什么?
  4. Deep learning:十九(RBM简单理解)
  5. SAP S/4HANA生产订单释放后自动同步到MES系统
  6. mysql affected rows_mysql_affected_rows函数定义与用法汇总
  7. KPI在小型产品团队中的实践
  8. 谷歌浏览器怎么设置字体 chrome默认字体设置方法
  9. Mac上显示出.m2文件夹并将IDEA中的Maven修改为阿里云镜像
  10. 自定义初学5——自定义View显示图片
  11. 阶段3 3.SpringMVC·_06.异常处理及拦截器_2 SpringMVC异常处理之演示程序异常
  12. Android 4.0 开机启动广播
  13. java在线ide_程序猿专用十大在线编译器(IDE)整理
  14. 查询语句 group by 分组
  15. java structs教程_Java教程 实战学习Struts实例
  16. 2022年数学建模国赛c题论文+代码(附详解)
  17. 软件测试简历上的职业技能怎么写,测试工程师岗位个人简历个人技能范文
  18. 这个发现是否会是RSA算法的BUG、或者可能存在的破解方式?
  19. 圆满收官,百花齐放!2022企业级低代码应用大赛获奖结果公布
  20. 什么是公链,私链,联盟链?

热门文章

  1. javaWeb服务详解【客户端调用】(含源代码,测试通过,注释) ——测试
  2. Python解决中文乱码问题
  3. 计算机网络产生的历史背景,网络技术背景及sdn概述.pdf
  4. mysql数据库新建一个递增的_分享一个mysql实验—基于数据库事务隔离级别RR及RC的测试...
  5. cas 登录之后不跳转_图解JWT如何用于单点登录
  6. Quartz定时任务的基本搭建
  7. mega x_[MEGA DEAL] 2020年完整的Java Master Class Bundle(96%)
  8. pojo 带参构造函数_带有Java Pojo作为输入输出示例的AWS Lambda函数
  9. HttpClient 4 API –获取状态代码-getStatusLine()。getStatusCode()示例
  10. adf开发_在EL表达式中引用ADF Faces组件