`
ajax
  • 浏览: 253915 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Restlet实战(二十七)压缩 (Compression)

    博客分类:
  • REST
阅读更多

在进入代码部分之前,还是贴出<<RESTful Web Service>>里对压缩的说明,毕竟这是本非常不错的书,而且书上说的比较清晰明了。

 

象XML文档这种文本格式的表示可以又很大的压缩率。HTTP客户端可以请求一个压缩版的表示,并为用户进行
透明的解压。其工作原理是这样的:客户端在发送HTTP请求时,在Accept-Ecoding包头里指出客户端支持那些
压缩算法。Accept-Encoding抱头又两个标准的值:compress和gzip

GET /resource.html HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip, compress

若服务器支持Accept-Ecoding请求报头里指出的压缩算法,那么它将先对表示进行压缩,然后再发给客户端。
Content-type响应报头的值不会因为服务器是否压缩而改变。但是服务器会再响应里附上一个
Content-Encoding报头,这样客户端就知道服务器返回的表示有没有压缩:

200 OK
Content-Type : text/html
Content-Encoding: gzip

客户端再收到服务器的响应后,将先用Content-Encoding响应报头里指出的算法来解压缩数据,然后按照
Content-Type响应报头指出的媒体类型来处理解压缩后的数据。通过采用压缩技术,只需增加少许复杂性就
可以节省大量带宽。

 

下面我们结合两种情况看看如何实现压缩(使用Restlet作为服务器和客户端):

 

1. 客户端向服务器发送GET请求,服务器返回一个压缩的表示给客户端

 

首先客户端发送请求,并指出客户端支持那些压缩算法:

 

Reference reference = new Reference("http://localhost:8080/restlet/resources/users/1");
Request get = new Request(Method.GET, reference);

List<Preference<Encoding>> encodings = new ArrayList<Preference<Encoding>>();
Preference<Encoding> pref = new Preference<Encoding>(Encoding.GZIP, 1.0f);
encodings.add(pref);
pref = new Preference<Encoding>(Encoding.COMPRESS, 0.5f);
encodings.add(pref);

get.getClientInfo().setAcceptedEncodings(encodings);

Client client = new Client(Protocol.HTTP);
Response response = client.handle(get);

 

/users/{userId}对应的资源是UserResource,那么服务器端接收到请求后,会做什么处理呢?服务器会首先判断客户端是否可以接受压缩的表示,并且支持那些算法,然后根据支持压缩算法的优先级别来决定使用那种算法来压缩表示。这里,为了测试方便,假设服务器端只支持GZIP算法,代码如下:

 

@Override
public void handleGet() {
	boolean isGZIP = false;
	List<Preference<Encoding>> encodings = getRequest().getClientInfo().getAcceptedEncodings();
	if (encodings != null) {
		for (Preference<Encoding> pre : encodings) {
			if (pre.getMetadata().equals(Encoding.GZIP)) {
				isGZIP = true;
				break;
			}
		}
	}
	Representation representation = null;
	if(isGZIP){
		representation = new EncodeRepresentation(Encoding.GZIP,
				new StringRepresentation(getUserXml(),
						MediaType.TEXT_PLAIN));
	}else{
		representation = new StringRepresentation(getUserXml(user), MediaType.TEXT_PLAIN);
	}
	
	getResponse().setStatus(Status.SUCCESS_OK);
	getResponse().setEntity(representation);	
}

 同样为了测试方便,我硬编码了一个压缩前的表示内容:

 

private String getUserXml(){
	StringBuffer userXml = new StringBuffer();
	
	userXml.append("<user id=\"1\">");
	userXml.append("<name>ajax</name>");
	userXml.append("<phone>13888888888</phone>");
	userXml.append("<email>ajax@iteye.com</email>");
	userXml.append("<address>Shanghai</address>");
	userXml.append("</user>");
	
	return userXml.toString();
}

 

至此,服务器端处理完成,那么客户端接收到服务器端返回的响应后,需要解压缩,当然了,需要首先判断服务器端使用的是那种压缩算法,看代码:

 

List<Encoding> _encodings = response.getEntity().getEncodings();
boolean isGZIP = false;

if (_encodings != null) {
	for (Encoding encoding : _encodings) {
		if (encoding.equals(Encoding.GZIP)) {
			isGZIP = true;
			break;
		}
	}
}
Representation rep = response.getEntity();
if(isGZIP){
	rep = new DecodeRepresentation(response.getEntity());
}

String testText = rep.getText();

 过程比较简单,不再多做解释。

 

2.客户端发送POST请求到服务器端,并且附送一个压缩的表示。

 

这种情况一般是客户端在请求时附送的表示非常耗费服务器资源,占用带宽,例如某些XML表示。为了测试,这里没有同服务器端反复协商的过程,直接发送使用GZIP压缩算法压缩过的表示。

 

Reference reference = new Reference("http://localhost:8080/restlet/resources/users/1");
Client client = new Client(Protocol.HTTP);

Representation representation = new EncodeRepresentation(Encoding.GZIP,
		new StringRepresentation(getUserXml(), MediaType.TEXT_PLAIN));

Response response = client.post(reference, representation);

assertTrue(response.getStatus().isSuccess());

 

看看服务器端怎么处理:

 

@Override
public void acceptRepresentation(Representation entity) throws ResourceException {
	try {
		String text = getRequest().getEntity().getText();
		
		System.out.println(text);
	} catch (IOException e1) {
		e1.printStackTrace();
	}
}

 

 咦,貌似不对,既然客户端压缩了表示,为什么服务器端没有解压缩? 是的,Restlet已经自动的做了解压缩,Restlet目前支持的压缩算法有:看DecodeRepresentation中的一段源代码:

 

    public static List<Encoding> getSupportedEncodings() {
        return Arrays.<Encoding> asList(Encoding.GZIP, Encoding.DEFLATE,
                Encoding.ZIP, Encoding.IDENTITY);
    }

 

那假设服务器端和客户端有自己约定的压缩算法,而这个算法又不在Restlet支持之列,怎么处理这种情况?可以在Application的实例中禁止进行解压缩:

 

getDecoderService().setEnabled(false);

 

这样,就可以使用约定的压缩算法进行相应的压缩与解压缩了。

 

分享到:
评论

相关推荐

    Restlet实战(二十六)事务 (Transaction)

    本文将深入探讨RESTful服务中的事务处理,并以《Restlet实战(二十六)事务 (Transaction)》为例进行解析。 首先,我们要理解RESTful服务中的核心原则之一是无状态(Stateless)。这意味着每个客户端请求都包含处理...

    restlet

    RESTlet是一款开源框架,专为构建基于REST(Representational State Transfer)原则的Web服务和应用程序设计。REST是一种轻量级的架构风格,广泛应用于互联网应用的开发,它强调通过简单的HTTP方法(如GET、POST、...

    RESTLET开发

    解压缩下载的文件到指定位置,假设解压缩后的文件夹路径为`%RESTLET_HOME%`。 #### 三、基于JAX-RS的REST服务实现 **JAX-RS (JSR-311)**是一种Java API,使得Java Restful服务的开发变得快速且简单。该API提供了...

    Restlet所需要的所有jar包

    本压缩包包含Restlet框架运行所需的全部jar文件,使得开发者可以便捷地在Java环境中开发、测试和部署RESTful服务。 Restlet框架的核心组件包括以下几个部分: 1. **客户端API**:提供了与REST服务器交互的能力,...

    org.restlet.jar

    org.restlet.jar

    Restlet in action 中文

    【Restlet in Action 中文】这本书是一本针对Java开发者介绍Restlet框架的实战指南,旨在帮助读者更好地理解和使用RESTful Web API。Restlet是一个开源的Web框架,它以面向对象的方式提供了一系列类和示例,使得...

    restlet2.1学习笔记项目代码

    Restlet是一个开源框架,专为构建RESTful(Representational State Transfer)Web服务而设计。REST是一种轻量级的架构风格,常用于构建可扩展、高性能的互联网应用程序。本项目是针对Restlet 2.1版本的学习笔记,...

    Restlet开发的Basic认证

    Restlet是一个轻量级的Java Web服务开发框架,它提供了构建RESTful(Representational State Transfer)应用程序的工具和API。REST是一种架构风格,强调简洁、无状态和可缓存的网络交互,常用于构建高性能、高可用性...

    Restlet开发实例

    接下来,我们进入"RESTLET开发实例(二)使用Component、Application的REST服务.doc"。在Restlet框架中,Component是整个应用的基础,它负责管理和协调多个Application。Application则是实际处理HTTP请求的实体,它...

    Restlet Client 插件安装包

    **Restlet Client插件安装包详解** 在现代的Web应用开发中,API(Application Programming Interface)扮演着至关重要的角色,尤其是RESTful API,它已成为构建分布式系统和微服务架构的标准。为了有效地测试和调试...

    org.restlet-2.3.0.jar 最新版本

    《深入理解org.restlet-2.3.0.jar:Java RESTful开发的得力助手》 在Java开发领域,REST(Representational State Transfer)架构风格已经成为构建Web服务的主流选择,而org.restlet-2.3.0.jar则是实现RESTful API...

    restlet实现最简单的restful webservice

    Restlet是一款开源框架,专为构建RESTful Web服务和客户端应用程序设计。REST(Representational State Transfer)是一种轻量级的架构风格,广泛用于构建互联网应用,因为它提供了高效、分布式的系统设计原则。本文...

    Restlet in action 英文 完整版

    第二章“Beginning a Restlet application”中,作者通过一个实际的例子引导读者逐步创建一个简单的Restlet应用。这包括设置开发环境、定义资源、处理HTTP方法(如GET、POST等)以及配置服务器。这一章节对于初学者...

    restlet项目

    Restlet项目是一个开源框架,专门用于构建RESTful(Representational State Transfer)Web服务。REST是一种软件架构风格,它强调简洁、可扩展性和无状态性,是Web服务设计的主流方式。Restlet框架提供了全面的工具集...

    RESTLET框架学习书籍

    #### 二、RESTLET框架的基础架构 - **RESTLET的基本概念**: - **Resources**:表示RESTLET中的资源,是RESTLET应用的核心组件,用于处理特定URL的HTTP请求。 - **Filters**:过滤器用于拦截请求和响应,实现如...

    Restlet与Spring 集成

    Restlet与Spring集成是将Restlet框架与Spring框架结合,以增强RESTful服务的开发能力。Restlet是一个轻量级的Java框架,专门用于构建REST(Representational State Transfer)架构风格的应用程序。它遵循JAX-RS...

    restlet1.1文档

    #### 二、Restlet的特点与应用场景 1. **统一的开发环境**:Restlet提供了一个统一的环境来处理不同的HTTP请求方法,使得开发者能够更专注于业务逻辑而不是底层协议。 2. **改进的部署灵活性**:Restlet允许开发者...

Global site tag (gtag.js) - Google Analytics