- 浏览: 251830 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
fjdingsd:
目前基于REST的Java框架不包括Jersey吗
Hello REST!!! -
qq690388648:
不错,说的很好!
Restlet实战(十四)如何在Restlet得到Servlet request和Session -
zhuanbiandejijie:
唉... 你09年就接触Restlet了.15年我才开始看Re ...
Hello REST!!! -
zmjiao:
client.options( 这个是那个包下面的? rest ...
Restlet实战(十八)Restlet如何产生WADL -
shihezichen:
对于最近很多人都在讨论的, 使用REST时就不应该掺杂事务的看 ...
Restlet实战(二十六)事务 (Transaction)
上篇文章我给出了如何在客户端和服务器端使用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实战(三十)(完结篇)运行流程之源代码分析(续)
2009-08-24 14:25 4119前面一篇文章分析了servlet里init方法,包括init方 ... -
Restlet实战(二十九)(完结篇)运行流程之源代码分析
2009-08-20 17:32 5230终于到了完结篇,也体 ... -
Restlet实战(二十七)压缩 (Compression)
2009-08-05 12:09 7151在进入代码部分之前,还是贴出<<RESTful W ... -
Restlet实战(二十六)事务 (Transaction)
2009-08-02 23:29 5322<<Restful Web Service> ... -
Restlet实战(二十五)缓存 (Cache)
2009-07-31 22:18 3942说明:以下部分文字说明摘自<<Restful We ... -
Restlet实战(二十四)获取参数值(续)
2009-07-31 14:44 10367这个系列之前已经有一篇文章写如何获取参数值,看Restlet实 ... -
欢迎加入Restlet圈子
2009-07-28 22:28 2757如果你进来是因为想看Restlet相关的文章,那么欢迎你加入r ... -
Restlet实战(二十三)实现条件GET (Conditional Get)
2009-07-28 17:47 4998先普及一下什么是条件GET,以下摘自<<Restf ... -
Restlet实战(二十二)仿造PUT和DELETE
2009-07-28 13:17 7152在Restlet实战(七)-提交和处理Web Form 中提到 ... -
Restlet实战(二十一)如何保护确定的资源(续)
2009-07-16 16:18 3962在Restlet实战(十七)如何保护确定的资源 中我给出一个如 ... -
Restlet实战(二十)使用Restlet之SSL
2009-07-15 21:37 3267待写 -
Restlet实战(十九)使用Restlet实现Web Service
2009-07-15 21:34 4283先说明本篇文章要实现的功能,仍然做一些假设,当前系统是基于Re ... -
Restlet实战(十八)Restlet如何产生WADL
2009-07-11 21:57 9802现在究竟REST是否需要WADL这种东西,有很多争论,有人说不 ... -
Restlet实战(十七)如何保护确定的资源
2009-07-11 21:55 3392在面向资源的架构中, ... -
Restlet实战(十六)结合源代码分析及使用Filter
2009-07-11 21:13 5709其实在Web应用中Filter对大家来说一点都不陌生,比如说在 ... -
Restlet实战(十五)如何与表示层交互
2009-07-10 13:51 5329首先还是设定一个应用场景,看看用restlet如何实现。 ... -
Restlet实战(十四)如何在Restlet得到Servlet request和Session
2009-07-09 16:39 11489如果你现在已经有一个web系统,而为了一些需求,你集成了res ... -
Restlet实战(十三)如何在Servlet中呼叫Restlet
2009-07-09 14:47 4500看到这个题目,或许你会问,你之前的很多文章不都是与servle ... -
Restlet实战(十二)获取参数值
2009-07-07 15:06 6908本篇文章将讲解三种不 ... -
Restlet实战(十一)结合源代码修改Restlet-Spring配置文件
2009-07-04 23:56 6129上篇文章结合了Restlet的源码分析了Restlet-spr ...
相关推荐
restlet2.0版本jee源码,例子,jar包,api等内容
NULL 博文链接:https://ajaxcn.iteye.com/blog/438237
restlet源代码,描述了restlet框架中每个类的具体实现
restlet2.1学习笔记项目代码
RESTLET开发实例(二)使用Component、Application的REST服务
restlet代码
restlet相关文档
restlet源代码,restlet jar包
Restlet的思想是:HTTP客户端与HTTP服务器之间的差别,对架构来...如果你确实需要的话,可以用Retrotranslator(http://retrotranslator. sourceforge.net/)轻易地把Restlet代码反移植(backport)到J2SE 4.0版上去。
restlet项目
Restlet Client插件是一款运行在chrome内核浏览器上的Web服务测试插件,该插件主要用于测试各种Web服务,能查看网站基本信息、浏览网页代码并能发送HTTP请求来测试网站Web服务,同时支持自动化API场景。用户在安装了...
Restlet与Spring 集成
一个简单的Restlet开发框架的Basic认证的例子
座便器电影 Restlet WS基于JWSUR源代码的修改。
Restlet所需要的所有jar包 一次下载,以后高枕无忧!
基于Spring的Restlet实例 代码和jar包
restlet入门helloworld示例
本文是对Restlet官方教程http://restlet.com/learn/tutorial/2.2/的中文翻译。
RESTLET框架学习书籍