- 浏览: 139678 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
邪恶八进制:
译的还不错,其实简单说、JPA三种继承映射体系如下:1.参照父 ...
[译文]JPA的实施模式:映射继承的层次体系 -
mondayw:
卓越上有售,地址:http://www.amazon.cn/m ...
翻译的第一本书出版了 -
黑暗浪子:
哪里有订?
翻译的第一本书出版了 -
mondayw:
不好意思,没有测试过,我以为这只是示范性的代码而已。
[译文]Java EE 6中的依赖注入——第1部分(二) -
jimmy.shine:
不知道你有无测试过这范例程序,在JBoss 6.0M2中,程序 ...
[译文]Java EE 6中的依赖注入——第1部分(二)
原文:Write Your First Google Wave Robot in Java
作者:Mark Watson
出处:http://www.devx.com/Java/Article/43342
[译文]使用Java编写你的第一个Google Wave机器人(上)
在App Engine上实现一个代理
就这个演示程序来说,代理必须能够完成三个步骤:
-
向我用来运行CookingSpace的测试服务器发起一个web service调用。
-
处理从web service调用中返回的JSON数据。(你可以在这里找到Java JSON库的文档。)
-
处理Wave事件。
发出一个web service调用
App Engine平台的一个限制就是,你必须使用某个特殊的URL提取服务来调用外部的web service,以下是演示机器人执行web service调用的代码:
String data = URLEncoder.encode("search_text", "UTF-8") + "=" + URLEncoder.encode(query, "UTF-8");
data += "&" + URLEncoder.encode("format", "UTF-8") + "=" + URLEncoder.encode("json", "UTF-8");
URL url = new URL("http://cookingspace.com");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = rd.readLine();
System.out.println("line: " + line);
wr.close();
rd.close();
JSONTokener jt = new JSONTokener(line);
//处理返回的JSON有效载荷
作者注:REST架构风格提倡使用HTTP GET来从数据源中获取数据表示,而使用HTTP PUT请求来创建及更新远端的数据源,尽管如此,PUT更常用,因此为了向你展示如何设置一个PUT请求,我决定在这一例子中使用这种方式,像http://cookingspace.com/?search_text=rice&format=json这样的GET请求同样也会很好地执行。 |
演示机器人的源代码包含了一个新的Java包com.cookingspace.rest和一个新的类ServiceCall,该类硬编码访问CookingSpace,如果看一下ServiceCall.java文件中的源代码的话,你就会发现其使用了JSON有效载荷中的数据来为符合搜索内容的食谱创建包含了格式化食谱(有成份、操作指南和营养数据)列表的串值,以下是一个看起来像返回的JSON有效载荷的例子(为了简洁起见,删除了许多文本内容)。
[[{"rating": 2.0, "name": "Arroz con Pollo", "directions": "Heat oil in a large skillet .....",
"num_served": 4, },
["Chicken (fryer)", "1 ", "unit ( yield from 1 lb ready-to-cook chicken)", "vegetable oil", ...],
[["carbohydrate", 43.60446125], ["energy_in_kcal", 1208.3971164],
["fat_mono_unsaturated", 17.0170589726], ["fat_poly_unsaturated", 8.7905745974],
["fat_saturated", 5.7239387098], ["fiber", 1.82729], ...], ....]]]
下一步,你将看到Wave演示机器人如何在类文件ServiceCall中使用这一代码。
实现Wave演示机器人
图5展示了Eclipse IDE工程的另一个视图,这次显示了例子需要的所有文件,需要注意的是添加的ServiceCall.java文件以及war/_wave目录下的文件。
图5. 添加了所有演示文件的App Engine工程:这是一个包含了演示特需的所有文件的Eclipse IDE工程视图
在使用Google App Engine的Eclipse插件创建新的App Engine工程的时候,Eclipse会自动创建文件src/META-INF/jdoconfig.xml,演示不会用到持久存储,所以你不需要理会该文件(可参阅我之前的关于DevX App Engine的文章,以了解使用App Engine数据存储的例子)。
目录war/_wave下包含的两个XML文件是值得注意的:capabilities.xml和profile.xml,capabilities.xml文件用来登记你希望你的机器人从Wave平台上接收的Wave事件:
<?xml version="1.0" encoding="utf-8"?>
<w:robot xmlns:w="http://wave.google.com/extensions/robots/1.0">
<w:version>4</w:version>
<w:capabilities>
<w:capability name="wavelet_participants_changed" content="true" />
</w:capabilities>
<w:profile name="CookingSpace" />
</w:robot>
capabilities的细则要求无论何时只要有人加入wave就通知机器人。(接下来的关于wave机器人servlet的讨论会解释如何处理这一事件。)在另一个wave机器人例子中,登记了其他的需要通知的事件(虽然不是在这此演示):
<w:capability name="wavelet_blip_created" content="true" />
<w:capability name="blip_submitted" content="true" />
文件war/_wave/profile.xml规定了演示机器人的名称:
<?xml version="1.0"?>
<wagent-profile>CookingSpace</wagent-profile>
CookingSpace机器人使用wave标题作为查找匹配的食谱的搜索字词(参加图6中的标题为“salmon rice”的例子)。
图6. 创建一个新的Wave:这是创建标题为“salmon rice”的新wave的例子
CookingSpace机器人的servlet
现在来到了处理来自Wave平台的Wave事件通知的servlet中,通知发生在CookingSpace机器人作为一个参与者加入到一个wave中时,因为大部分的事件处理行为都由ServcieCall类来负责,所以这一servlet的实现是很简单的:
package com.cookingspace;
import com.cookingspace.rest.ServiceCall;
import java.util.logging.Logger;
import com.google.wave.api.AbstractRobotServlet;
import com.google.wave.api.Blip;
import com.google.wave.api.RobotMessageBundle;
import com.google.wave.api.TextView;
import com.google.wave.api.Wavelet;
@SuppressWarnings("serial")
public class CookingSpaceProxyServlet extends AbstractRobotServlet {
private static final Logger log = Logger.getLogger(CookingSpaceProxyServlet.class.getName());
@Override
public void processEvents(RobotMessageBundle events) {
log.info("Entered processEvents " + events);
Wavelet wavelet = events.getWavelet();
if (events.wasSelfAdded()) {
Blip blip = wavelet.appendBlip();
TextView textView = blip.getDocument();
textView.append("I'm alive and ready to provide recipes. For more information: ");
String title = wavelet.getTitle();
log.info("CookingSpace.com Recipe lookup web service: " + title);
// String text = eventBlip.getDocument().getText().trim(); // we don't need blip text
if (title.length() > 3 && title.length() < 30) {
String results = new ServiceCall(title).results();
textView.append("CookingSpace.com Recipe lookup web service: " + title + "\n\n" + results);
}
}
}
}
日志记录器(logger)用来把有用的信息插入到该应用的App Engine日志中,无论你是写简单的App Engine应用还是Wave机器人,你都会发现App Engine管理控制台的日志查看器是非常有用的,既可以跟踪应用的错误,又可以一般性地理解在处理请求的过程中发生了什么。我把这些日志记录器的调用当作是调试的打印输出,在对我的App Engine应用的正常运行感到满意之后,我通常会去掉他们。
方法调用events.getWavelet()返回Wave系统上的触发了被处理事件的wavelet,wavelet是wave文档的组成部分,由一个或多个blip组成,blip是文档的最小组件。
如果事件是由被添加到wave中的CookingSpace机器人触发的话,方法调用events.wasSelfAdded()返回一个为真的布尔值,如果是这种情况,那么就希望获得wave的标题。“blip”是wave的组成部分,诸如初始的wave内容等等,在当前情况中,该bilp就是CookingSpace机器人将要添加到原来的wave中的新信息(参见图7)。
图7. 把CookingSpace机器人加到新wave中:这是把CookingSpace机器人加到标题为“salmon rice”的新wave中的例子。
Blip的文本视图显示它的标题和文本内容,前面的代码用到了blip的标题但忽略了blip的文本内容,它把标题传递给ServceCall这一实用工具类,以发起到cookingspace.com的web service调用并格式化返回的食谱(如果有找到的话),然后把食谱的文本内容添加到由Blip blip = wavelet.appendBlip()这一调用所创建的新blip中。
就是这样了!你已经完成了实现机器人的工作,图8展示了添加了CookingSpace机器人后的Wave web客户端,图9展示了客户端显示由机器人添加的食谱,图10则给出了图9中显示的食谱的营养数据。
图8. 在添加CookingSpace机器人之后:这是添加了CookingSpace机器人后的Wave web客户端。
图9. 显示机器人添加的食谱:这是显示由机器人添加的通过查询“salmon rice”获得的食谱
图10. 显示机器人添加的食谱的营养:这是显示图9中的食谱的营养数据的wave web客户端。
如果希望以Wave机器人的方式重用你的任何应用的话,这一简单的演示程序提供了一种快速启动的方法,演示程序的几乎所有的工作都已在ServiceCall这一实用工具类中开发并测试过了。当在Wave机器人方面积攒了更多经验之后,你只需要几分钟时间就可以完成开始一个新的Wave机器人工程的“样板”工作:
-
创建一个新的Eclipse工程
-
添加所需的Wave客户端JAR文件
-
编写事件处理servlet
在Wave机器人开发过程中会遇到的问题
在开发Wave机器人的时候,我遇到了几种常见的问题:
-
因为无法本地测试Wave事件/机器人的交互而导致的开发周期缓慢
-
改动Wave API和我的机器人有时会导致接收不到事件通知,两种情况都是因为Wave平台还处于测试状态中。
不过这些问题都不是致命的。因为Wave机器人实际上是web service,因此我在本地测试了这些服务的应用代码,这样,当开始进行测试部署时,我通常只需要处理所遇到的Wave平台本身的问题,因此,测试尽可能都是在本地进行的,因为App Engine平台的构建/部署/测试周期只需要几分钟的时间。
可能有时候要耐心地处理一些Wave服务问题,如果我引发了一个Wave事件(例如创建一个新Wave并添加我的机器人),但这一事件没有在App Engine的控制台应用日志中显示出来的话,我通常就在另一工程上工作,然后再来重试我的测试,随着Wave平台越来越稳定,这种做法可能就变得不是那么需要了。
进一步
你现在应该可以使用Google Wave平台作为又一个发布和部署平台了,本文开始部分的图1和图2还展示了Facebook作为现有web应用的另一个发布平台的情形,在使用本文中的例子来把你的某个web应用以Wave机器人的方式发布之后,你可以尝试着根据这些简单的步骤来把它以Facebook应用的方式进行发布(如果你还没有这样做过的话)。
发表评论
-
[译文]技巧:防范代码的终结器漏洞
2011-08-02 11:11 741你的Java代码有可能会因终结操作带来的漏洞而易受到攻击,了解 ... -
[译文] 一种减少多线程Java应用的工作队列中的竞争和开销的方法
2011-06-21 10:08 986许多的服务器应用,比如说Web服务器、应用服务器、数据库服务器 ... -
[译文]Java SE 7带来更好的资源管理:不仅仅是语法糖
2011-06-18 19:55 773本文介绍了Java Platform, Standard Ed ... -
[译文]双重检查锁定和单件模式
2011-05-06 11:50 840所有的编程语言都会有分享一些它们的惯用技法,其中的 ... -
RJC501:为周转期付出的代价有多大?
2011-04-18 16:43 807通过重载Java类(Reloading Java ... -
RJC401:HotSwap和JRebel——幕后的故事
2011-04-11 16:31 1020在本文中,我们会回顾类在没有动态类加载器情况下的重载方式;我们 ... -
RJC301:Web开发——Tomcat、GlassFish、OSGi、Tapestry等服务器和框架中的Classloader
2011-04-04 15:26 946在本文中,我们会回顾真实的服务器、容器和框架是如何使用动态的类 ... -
RJC201:ClassLoader的泄漏是如何发生的?
2011-03-28 19:58 864你如果使用Java编程已有一段时间的话,那么你就会知道内存泄漏 ... -
jQuery的.bind()、.live()和.delegate()之间的区别
2011-03-19 22:01 829.bind()、.live()和.delegate()之间的 ... -
示例:JavaScript中的后续传递风格
2011-03-19 21:57 830本文介绍了CPS所扮演的两种角色——作为JavaScript中 ... -
[译文]开发者见解系列,第3部分:编写代码的步骤(下)
2010-07-27 22:11 877原文:The Developer Insight ... -
[译文]开发者见解系列,第3部分:编写代码的步骤(上)
2010-07-27 22:05 1114原文:The Developer Insight Series ... -
[译文]开发者见解系列,第2部分:谈谈编码(下)
2010-07-14 22:31 853原文:The Developer Insight Series ... -
[译文]开发者见解系列,第2部分:谈谈编码(上)
2010-07-14 22:26 1077原文:The Developer Insight Series ... -
[译文]开发者见解系列,第1部分:编写傻瓜代码——来自四位首席Java开发者的建议(下)
2010-06-28 12:32 827原文:The Developer Insight Series ... -
[译文]开发者见解系列,第1部分:编写傻瓜代码——来自四位首席Java开发者的建议(上)
2010-06-28 12:25 1411原文:The Developer Insight Series ... -
[译文] Java EE 6中的DataSource资源的定义
2010-05-20 12:29 1931原文:DataSource Resource Definiti ... -
[译文] Java Applets和ASP.net——你可让他们玩到一起吗?
2010-05-13 18:01 1686原文:Java Applets, ASP.net - Can ... -
[译文]使用Java编写你的第一个Google Wave机器人(上)
2010-01-25 21:02 1321原文:Write Your First Google Wave ... -
[译文]一些Java并发技巧
2009-12-20 18:25 1015原文:Some Java Concurrency Tips ...
相关推荐
机器人Robots译文.doc
六足舞蹈机器人 外文翻译
毕业论文的专业译文,计算机专业,关于java堆的一些内容。中英文全。
中文译文:工业混合喷涂机器人的精确动态建模与控制参数设计 摘要:为了提高混合机器人在非线性动力学和摩擦下的性能,工业机器人领域已广泛应用前馈补偿。然而,由于混合动力机器人摩擦模型复杂、耦合性强、动态...
国际上对机器人的研究,以论文报告的形式展现出来,先进机器人已经开始与编程水乳交融,机器人已经越来越走入行业应用,如保姆机器人,小度,小米,各种平台助手成为机器人发展的一个象征,
Clojure是一个JVM的动态函数式语言,最近发布了1.0版本,版本中Clojure提供了一个健壮的代码。Clojure是一套发展快速的新的编程语言,特别是,它为多核计算做了新的解决方案。在今后的软件设计中无论使用Clojure语言...
本文提出了一种工业机器人的最优轨迹规划方法,该方法使用三次多项式曲线连接相邻路径点,从而使关节轨迹曲线更平滑。以安川六自由度工业机器人为例,利用MATLAB的遗传算法工具箱,确定了适应度函数和约束条件函数,...
本资源原文为java-for-Anylogic-user英文版,即面向Anylogic用户的Java开发,本人纯手工翻译,讲述以拖放方式以外的编程思路,对于建立复杂系统有很大...这是一个信息论,可以在模型中进行数据操作以及智能体的搭建。
JSP技术使用Java编程语言编写类XML的tags和scriptlets,来封装产生动态网页的处理逻辑。网页还能通过tags和scriptlets访问存在于服务端的资源的应用逻辑。JSP将网页逻辑与网页设计和显示分离,支持可重用的基于组件...
1 绪论 1 1.1 研究背景及意义 1 1.2 国内外小型轮式机器人发展概况 2 1.2.1 国外研发概况 2 1.2.2 国内现状 5 1.2.3 国内外现状总结 7 1.3 小型轮式机器人的发展趋势 7 1.4 论文研究内容与主要结构 7 1.4.1 研究内容...
译文:Fork and Join: Java Can Excel at Painless Parallel Programming Too!(Fork and Join Java也可以轻松地编写并发程序)
计算机类专业毕业设计外文翻译的原文及译文。已经排版,下载即用。
中文译文B 爬楼机器人全文共6页,当前为第1页。 爬楼机器人全文共6页,当前为第1页。 轮组式爬楼机器人的设计与实现 引言 爬楼机器人是一种能适应多种参数楼梯及复杂障碍的移动机器人。本设计通过轮组交替变换的方式...
Generics_in_the_Java_Programming_Language的中文译文
java并发底层的一些概念、原理。 java5、java6中常用并发类、并发集合的属性和使用方法。
JAVA外文文献+翻译.pdf
有关java,jsp类论文可用的英文论文及中文译文,两个文件一个是英文原文,一个是翻译
国际先进机器人技术(IARP)第十七次联合协调讨论会报告译文集
java2007【搜狗文档翻译_译文_英译中】1
关于java的外文文献中英文对照都有