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

Restlet实战(二十八)源代码分析之压缩 (Compression)

    博客分类:
  • REST
阅读更多

上篇文章我给出了如何在客户端和服务器端使用Restlet实现表示的压缩,这一篇将结合源代码看看Restlet的API是如何支持压缩的。

 

首先看解压缩,开发中的代码:

 

Representation rep = new DecodeRepresentation(response.getEntity());
String testText = rep.getText();

 

当然了,从response返回的Entity就是压缩的表示,所以把它塞到DEcodeRepresentation的构造函数里,看一下DecodeRepresentation构造函数做了些什么:

 

public DecodeRepresentation(Representation wrappedRepresentation) {
	super(wrappedRepresentation);
	this.canDecode = getSupportedEncodings().containsAll(
			wrappedRepresentation.getEncodings());
	this.wrappedEncodings = new ArrayList<Encoding>();
	this.wrappedEncodings.addAll(wrappedRepresentation.getEncodings());
}

 

上面这段代码首先会判断当前表示的压缩算法在Restlet里是否支持,注意,这个参数很重要,如果这里判断是不支持的算法,则后续代码就不会解压缩,实际上也不知道该如何解压缩。其余的几行代码就是保存一下参数。

 

当所有参数设置完成以后,在客户端调用getText想得到解压缩后的表示,以做进一步的处理。

 

@Override
public String getText() throws IOException {
	String result = null;

	if (canDecode()) {
		result = ByteUtils.toString(getStream(), getCharacterSet());
	} else {
		result = getWrappedRepresentation().getText();
	}

	return result;
}

 

上述这段代码也就是我之前所说的首先会判断是否是支持的压缩算法,这里,如果是直接的压缩算法,也就是可以解压缩,就走解压缩的流程,否则,直接从包裹的表示里面取出表示的内容。代码里调用了getStream方法,我继续深入进去看一下:

 

@Override
public InputStream getStream() throws IOException {
	InputStream result = null;

	if (canDecode()) {
		result = getWrappedRepresentation().getStream();
		for (int i = this.wrappedEncodings.size() - 1; i >= 0; i--) {
			if (!this.wrappedEncodings.get(i).equals(Encoding.IDENTITY)) {
				result = getDecodedStream(this.wrappedEncodings.get(i),
						result);
			}
		}
	}

	return result;
}

 这段代码是根据表示的内容,返回一个Stream。在上述方法里调用了getDecodedStream,这个方法就是真正解压缩的方法,从下面这个方法,我闷也能看出,Restlet使用了Java提供的解压缩的类,包括的压缩类型:GZIP、ZIP、DEFLATE,而IDENTITY是缺省编码,表示不进行任何编码转换,所以,遇到这种情况,代码会抛出一个IOException。

 

private InputStream getDecodedStream(Encoding encoding,
		InputStream encodedStream) throws IOException {
	InputStream result = null;

	if (encodedStream != null) {
		if (encoding.equals(Encoding.GZIP)) {
			result = new GZIPInputStream(encodedStream);
		} else if (encoding.equals(Encoding.DEFLATE)) {
			result = new InflaterInputStream(encodedStream);
		} else if (encoding.equals(Encoding.ZIP)) {
			final ZipInputStream stream = new ZipInputStream(encodedStream);
			if (stream.getNextEntry() != null) {
				result = stream;
			}
		} else if (encoding.equals(Encoding.IDENTITY)) {
			throw new IOException(
					"Decoder unecessary for identity decoding");
		}
	}

	return result;
}

 

 

再来看看压缩的部分,客户端我们通常会这样写:

 

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

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

 

当客户端第一行代码被调用时候,对应的源代码如下: 

 

public EncodeRepresentation(Encoding encoding,
		Representation wrappedRepresentation) {
	super(wrappedRepresentation);
	this.canEncode = getSupportedEncodings().contains(encoding);
	this.encodings = null;
	this.encoding = encoding;
}

 

 代码比较简单,就是判断一下客户端指定的压缩算法Restlet是否支持,因为我们当前用Restlet作为请求的客户端,所以,采用的压缩算法,必须是Restlet支持的,否则,服务器端接收到表示后,也因为不支持压缩算法而不进行解压缩。

 

当客户端提交请求,如上述代码:client.post(reference, representation);,则EncodeRepresentation的write方法被调用:

 

@Override
public void write(OutputStream outputStream) throws IOException {
	if (canEncode()) {
		DeflaterOutputStream encoderOutputStream = null;

		if (this.encoding.equals(Encoding.GZIP)) {
			encoderOutputStream = new GZIPOutputStream(outputStream);
		} else if (this.encoding.equals(Encoding.DEFLATE)) {
			encoderOutputStream = new DeflaterOutputStream(outputStream);
		} else if (this.encoding.equals(Encoding.ZIP)) {
			final ZipOutputStream stream = new ZipOutputStream(outputStream);
			if (getWrappedRepresentation().getDownloadName() != null) {
				stream.putNextEntry(new ZipEntry(getWrappedRepresentation()
						.getDownloadName()));
			} else {
				stream.putNextEntry(new ZipEntry("entry"));
			}

			encoderOutputStream = stream;
		} else if (this.encoding.equals(Encoding.IDENTITY)) {
			// Encoder unecessary for identity encoding
		}

		if (encoderOutputStream != null) {
			getWrappedRepresentation().write(encoderOutputStream);
			encoderOutputStream.finish();
		} else {
			getWrappedRepresentation().write(outputStream);
		}
	} else {
		getWrappedRepresentation().write(outputStream);
	}
}

 

这个方法所做的,与解压缩刚好相反,在解压缩时,我们通过使用Java标准的压缩类库,去得到一个解压缩后的输入流,那么与之对应的,在压缩时候,就需要将表示压缩成一个输出流,另外,根据客户端指定的压缩算法,采用不同Java压缩类来实现。当然,在write方法调用之前,还会调用本类或者父类的其它的一些方法,但是这个不是本篇关注的重点。

 

 

 总结:结合上篇文章以及本篇,应该能明白Restlet是如何实现解压缩的,根据源代码的讲解,在设计客户端的时候,如何有效的避免一些陷阱,有效的、快速的设计客户端。

 

 

 

分享到:
评论

相关推荐

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

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

    restlet2.0版本jee源代码

    了解了这些基本概念后,你可以通过解压"restlet-jee-2.0.14"压缩包,查看源代码、例子和API文档,更深入地学习Restlet 2.0如何在Java EE环境中实现REST服务。这将有助于你开发出高效、灵活且易于维护的Web应用程序。

    restlet源代码

    restlet源代码,描述了restlet框架中每个类的具体实现

    restlet2.1学习笔记项目代码

    本项目是针对Restlet 2.1版本的学习笔记,包含了实际的项目代码,旨在帮助开发者更好地理解和应用Restlet框架。 在Restlet 2.1中,有几个关键概念和组件值得深入探讨: 1. **组件(Component)**:Restlet框架的...

    restlet

    文件列表中的"RESTlet"可能是RESTlet框架的源代码、文档或示例应用。通过学习这些资料,开发者可以深入理解RESTlet的工作原理,掌握如何使用RESTlet构建RESTful服务和客户端应用,从而提升其在Web服务开发领域的专业...

    restlet代码

    restlet代码

    Restlet开发的Basic认证

    5. **示例代码**:在`authorizationControl`这个文件夹中,可能包含了实现上述功能的Java源代码示例。例如,一个名为`BasicAuthenticator`的类,它继承了`Authenticator`,并在`authenticate`方法内进行用户验证。...

    Restlet所需要的所有jar包

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

    RESTLET开发

    RESTLET的核心目标之一是遵循Roy Fielding博士在其关于REST的博士论文中提出的理念,同时确保其提供的功能与这些理念保持一致。 RESTLET的另一个显著特点在于它提出了一种统一的Web视图,这种视图不仅适用于服务器...

    RestletClient接口调试

    RestletClient允许你以文本、源代码或文件形式输入这些数据。 3. **发送请求**:完成配置后,点击“发送”按钮,RestletClient将执行请求,并显示服务器的响应。这包括状态码(如200表示成功,404表示未找到),...

    restlet-j2ee-2.0.15.rar

    Restlet是一款轻量级的Java库,专门设计用于构建RESTful(Representational State Transfer)Web服务。REST是一种软件架构风格,常用于设计网络应用程序,强调使用HTTP协议来处理客户端与服务器之间的通信。RESTlet...

    org.restlet.jar

    org.restlet.jar

    Restlet in action 中文

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

    Restlet与Spring 集成

    - **依赖注入**:通过Spring的DI,可以在不修改代码的情况下改变服务的行为,如更换数据源、添加日志记录等。 - **AOP支持**:可以利用Spring的AOP功能实现事务管理、权限控制和异常处理。 - **测试友好**:由于服务...

    Restlet Client 插件安装包

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

    RESTLET框架学习书籍

    ### RESTLET框架学习知识点 #### 一、RESTLET框架概览 - **RESTLET框架简介**:RESTLET是一个面向对象的Java开源框架,用于构建RESTful应用和服务。它旨在简化Web应用开发,允许开发者充分利用REST架构的优势。...

    Restlet开发实例

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

    restlet1.1文档

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

Global site tag (gtag.js) - Google Analytics