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

在某些情况下,您的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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361460.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C函数篇(recv函数)

简述 从一个套接口接收数据。表头文件&#xff1a;#include<sys/types.h>#include<sys/socket.h>int PASCAL FAR recv( SOCKET s, char FAR* buf, int len, int flags);s&#xff1a;一个标识已连接套接口的描述字。buf&#xff1a;用于接收数据的缓冲区。len&…

js文字排序的方法

拼音排序&#xff1a; var arr [{ a: 1, b: "我" }, { a: 1, b: "是" }, { a: 1, b: "帅" }, { a: 1, b: "哥" }, { a: 1, b: "你" }, { a: 1, b: "服" }, { a: 1, b: "不" }];arr.sort(function comp…

线程池之外:Java并发并不像您想象的那么糟糕

Apache Hadoop&#xff0c;Apache Spark&#xff0c;Akka&#xff0c;Java 8流和Quasar&#xff1a; 针对Java开发人员的经典用例以及最新的并发方法 关于并发性更新概念的讨论很多&#xff0c;但是许多开发人员还没有机会将他们的想法缠住。 在本文中&#xff0c;我们将详细介…

编写高质量的代码,改善c#程序的157个建议_之1~10

//编写高质量的代码&#xff0c;改善c#程序的157个建议# 1、正确操作字符串## 1* 确保尽量少的装箱* 避免分配额外的内存空间1. 会进行一次装箱C#string str1"str1"9;2. 没有装箱&#xff0c;调用的是整型的ToString方法C#string str2"str2"9.ToString();#…

vue中使用Ueditor编辑器 -- 1

一、 下载包&#xff1a; 从Ueditor的官网下载1.4.3.3jsp版本的Ueditor编辑器&#xff0c;官网地址为&#xff1a;http://ueditor.baidu.com/website/download.html 下载解压后会得到如果下文件目录&#xff1a; 将上述Ueditor文件夹拷贝到vue项目的static文件夹中&#xff0…

编译原理--递归下降分析实验C++

一、实验项目要求 1.实验目的 根据某一文法编制调试递归下降分析程序&#xff0c;以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 2.实验要求 对下列文法&#xff0c;用递归下降分析法对任意输入的符号串进行分析&#xff1a; &#…

浅析路径遍历漏洞 文/饭

许多的Web应用程序一般会有对服务器的文件读取查看的功能&#xff0c;大多会用到提交的参数来指明文件名&#xff0c;形如&#xff1a;http://www.nuanyue.com/getfileimage.jgp 当服务器处理传送过来的image.jpg文件名后&#xff0c;Web应用程序即会自动添加完整路径&#xff…

摆脱困境:在DbUnit数据集中使用空值

如果我们正在为使用Spring Framework的应用程序编写集成测试&#xff0c;则可以通过使用Spring Test DbUnit将DbUnit与Spring测试框架集成。 但是&#xff0c; 这种集成并非没有问题 。 通常&#xff0c;我们必须在运行测试之前向数据库中插入空值&#xff0c;或者验证保存到…

artdialog5 bug

1.使用artdialog5时&#xff0c;使用两个输入框传值&#xff0c;一直无法取到值&#xff0c;使用简单的ID无法取到值&#xff0c;如idbranch..改为idbranch_str_dialog就可以了&#xff0c;问题是解决了&#xff0c;可是没有找到原因所在&#xff01; 转载于:https://www.cnblo…

vue中通过js控制页面样式方法

在使用vue.js框架的时候&#xff0c;有时候会希望在页面渲染完成之后&#xff0c;再执行函数方法来处理初始化相关的操作&#xff0c;如果只处理页面位置、宽或者高时&#xff0c;必须要在页面完全渲染之后才可以&#xff0c;页面没有加载完成之前&#xff0c;获取到的宽高不准…

Memcached入门指南

1 概览 Memcached是一个免费开源&#xff0c;高性能的&#xff0c;分布式内存对象缓存系统&#xff0c;为了加快动态web应用程序&#xff0c;减轻数据库负载。 Memcached是一个内存中的基于键/值存储任意数据小片段&#xff08;字符&#xff0c;对象&#xff09;&#xff0c;存…

css正則匹配、模糊匹配

//所有class包含font-red的p标签 p[class~"font-red"] {color: red;} [abc^"def"] 选择 abc 属性值以 "def" 开头的所有元素 [abc$"def"] 选择 abc 属性值以 "def" 结尾的所有元素 [abc*"def"] 选择 abc 属性值中…

快速指南:剖析JBoss BPM跨进程通信

&#xff08;文章来宾与北美红帽公司高级解决方案架构师杰伊保拉杰共同撰写&#xff09; 几周的提示与技巧文章将深入探讨JBoss BPM Suite&#xff0c;特别是有关如何在两个流程之间进行通信的问题。 在进入解决方案详细信息之前&#xff0c;让我们首先约束将要讨论的用例。 …

字符串中全角半角之间的转换

前几天&#xff0c;在做表单验证的时候&#xff0c;发现用户在输入表单内容的时候&#xff0c;正常情况下都是半角输入&#xff0c;但是也有可能是全角输入&#xff0c;所以就牵扯到全角输入内容的验证&#xff0c;这里便提供全角和半角之间的转换函数&#xff0c;与大家分享一…

Android HAL 层,三个重要的结构体的源码~

最近在学习android HAL 层 ~ 离不开这三个数据结构~~先贴出来 typedef struct hw_module_t { /** tag must be initialized to HARDWARE_MODULE_TAG */ uint32_t tag; /** major version number for the module */ uint16_t version_major; /** minor version number …

React使用的扩展

待续。。。 转载于:https://www.cnblogs.com/wenxuehai/p/11387188.html

使用命令行工具创建WildFly OpenShift应用程序

通过使用快速入门&#xff0c;可以在OpenShift上轻松配置WildFly的新实例。 只需单击一下&#xff0c;您就可以准备就绪&#xff01; 通常&#xff0c;OpenShift的高级用户使用命令行工具 。 但是&#xff0c;您无法使用CLI工具创建WildFly墨盒。 但现在已解决错误1134134 。 …

word-break属性和css换行显示

这几天在做项目的时候&#xff0c;遇到了比较棘手的问题&#xff0c;便是在一个标签里边展示内容&#xff0c;如果说展示中文汉字&#xff0c;一点问题都没有&#xff0c;但是只要连续展示英文字母或者中文的标点符号&#xff08;中间不带空格&#xff09;&#xff0c;那么所渲…

第四种行转列

--动态处理 select A.StuName,A.BZKTypeName,cast(A.BKCODE as varbinary(MAX)) even, row_number() over (partition by StuName,BZKTypeName order by getdate()) ID into #t1 from BKLIST A --where StuName林健辉 declare sql1 varchar(max) declare sql2…

React-router的基本使用

1、安装使用 $ npm install -S react-router import { Router, Route, hashHistory } from react-router;render((<Router history{hashHistory}><Route path"/" component{App}/></Router> ), document.getElementById(app)); 1.1、版本问题 reac…