- 浏览: 144732 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
邪恶八进制:
译的还不错,其实简单说、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 770你的Java代码有可能会因终结操作带来的漏洞而易受到攻击,了解 ... -
[译文] 一种减少多线程Java应用的工作队列中的竞争和开销的方法
2011-06-21 10:08 1023许多的服务器应用,比如说Web服务器、应用服务器、数据库服务器 ... -
[译文]Java SE 7带来更好的资源管理:不仅仅是语法糖
2011-06-18 19:55 798本文介绍了Java Platform, Standard Ed ... -
[译文]双重检查锁定和单件模式
2011-05-06 11:50 876所有的编程语言都会有分享一些它们的惯用技法,其中的 ... -
RJC501:为周转期付出的代价有多大?
2011-04-18 16:43 842通过重载Java类(Reloading Java ... -
RJC401:HotSwap和JRebel——幕后的故事
2011-04-11 16:31 1049在本文中,我们会回顾类在没有动态类加载器情况下的重载方式;我们 ... -
RJC301:Web开发——Tomcat、GlassFish、OSGi、Tapestry等服务器和框架中的Classloader
2011-04-04 15:26 987在本文中,我们会回顾真实的服务器、容器和框架是如何使用动态的类 ... -
RJC201:ClassLoader的泄漏是如何发生的?
2011-03-28 19:58 897你如果使用Java编程已有一段时间的话,那么你就会知道内存泄漏 ... -
jQuery的.bind()、.live()和.delegate()之间的区别
2011-03-19 22:01 861.bind()、.live()和.delegate()之间的 ... -
示例:JavaScript中的后续传递风格
2011-03-19 21:57 865本文介绍了CPS所扮演的两种角色——作为JavaScript中 ... -
[译文]开发者见解系列,第3部分:编写代码的步骤(下)
2010-07-27 22:11 916原文:The Developer Insight ... -
[译文]开发者见解系列,第3部分:编写代码的步骤(上)
2010-07-27 22:05 1145原文:The Developer Insight Series ... -
[译文]开发者见解系列,第2部分:谈谈编码(下)
2010-07-14 22:31 889原文:The Developer Insight Series ... -
[译文]开发者见解系列,第2部分:谈谈编码(上)
2010-07-14 22:26 1117原文:The Developer Insight Series ... -
[译文]开发者见解系列,第1部分:编写傻瓜代码——来自四位首席Java开发者的建议(下)
2010-06-28 12:32 863原文:The Developer Insight Series ... -
[译文]开发者见解系列,第1部分:编写傻瓜代码——来自四位首席Java开发者的建议(上)
2010-06-28 12:25 1454原文:The Developer Insight Series ... -
[译文] Java EE 6中的DataSource资源的定义
2010-05-20 12:29 1966原文:DataSource Resource Definiti ... -
[译文] Java Applets和ASP.net——你可让他们玩到一起吗?
2010-05-13 18:01 1728原文:Java Applets, ASP.net - Can ... -
[译文]使用Java编写你的第一个Google Wave机器人(上)
2010-01-25 21:02 1360原文:Write Your First Google Wave ... -
[译文]一些Java并发技巧
2009-12-20 18:25 1055原文:Some Java Concurrency Tips ...
相关推荐
《国际先进机器人技术(IARP)第十七次联合协调讨论会报告译文集》是一部集大成之作,它详尽地记录了全球机器人领域的最新研究成果和技术动态。在当今科技飞速发展的时代,机器人技术不再仅仅是科幻小说中的概念,...
机器人是一种自动控制、可编程、多功能、多轴操纵的机器,可以固定在一处或移动使用,广泛应用于工业自动化应用。其核心特点在于“可编程”和“多功能”,这使得机器人能够在多种制造任务中灵活适应。 “可编程”...
《国际先进机器人技术(IARP)第十七次联合协调讨论会报告译文集》是一部集大成之作,全面展示了全球机器人技术领域的最新进展和未来趋势。IARP,即International Advanced Robotics Program,是一个由世界各国...
JSP使用Java语言编写类似于XML的标签和脚本,以封装动态内容生成的逻辑。网页通过这些标签和脚本可以访问服务器端的资源和应用逻辑。因此,JSP促进了可重用组件的使用,比如Servlets、JavaBeans和基于Java的Web应用...
六足舞蹈机器人 外文翻译
本资源原文为java-for-Anylogic-user英文版,即面向Anylogic用户的Java开发,本人纯手工翻译,讲述以拖放方式以外的编程思路,对于建立复杂系统有很大...这是一个信息论,可以在模型中进行数据操作以及智能体的搭建。
随着Java技术的不断成熟和改进,1995年,Sun公司正式发布了Java 1.0版本,其跨平台、一次编写,到处运行的特性得到了广泛的认可。Java的虚拟机(JVM)允许编译后的Java代码在任何支持Java的设备上运行,这极大地推动...
它的设计目标是“一次编写,到处运行”(Write Once, Run Anywhere),这意味着用Java编写的代码可以在任何支持Java的平台上运行,无需重新编译。Java的特点包括垃圾回收机制、自动内存管理、丰富的类库和强大的网络...
1. **线程基础**:线程是操作系统分配CPU时间的基本单元,Java通过`Thread`类提供对线程的支持。创建线程主要有两种方式:继承`Thread`类和实现`Runnable`接口。理解线程的生命周期(新建、就绪、运行、阻塞、等待和...
然而,由于混合动力机器人复杂的摩擦模型、强烈的耦合效应和动态时变特性,实现精确控制一直是一个极具挑战的问题。为了应对这一挑战,本文提出了一种精确的动态建模与控制参数设计方法,旨在提高混合喷涂机器人的...
1. JAVA语言的重要性 JAVA语言之所以重要,是因为它可以解决传统的计算机编程问题,同时也能够解决互联网上编程问题。 2. 客户端编程 在传统的Web服务器-浏览器设计中,服务器提供静态页面,而客户端浏览器只是...
Java语言的设计目标是提供一个“Write Once, Run Anywhere”的平台,使得程序员可以轻松地develop和deploy应用程序。 在Java语言中,类和对象是基本的概念。类是一个模板,用于创建对象,对象是类的实例化。Java...
在工业自动化领域,机器人技术的快速发展已经使得它们成为制造业不可或缺的一部分。工业机器人的轨迹规划作为核心环节之一,影响着机器人的运行效率和工作质量。本文介绍了一种基于遗传算法的工业机器人最优时间轨迹...
Java 程序只需“一次编写,到处运行”(Write Once, Run Anywhere, WORA),这意味着开发者可以编写一次代码,就能在任何支持 Java 的平台上运行,无论是 Windows、Linux 还是 macOS,这极大地提升了开发效率和软件...
虽然"java2007【搜狗文档翻译_译文_英译中】1"这个标题没有直接指出Java在Twitter中的具体作用,但可以推测Java可能在构建和分析Twitter的基础设施、数据处理和用户交互方面发挥了重要作用。微博客和社交网络分析的...
第一章:基本概念 * public:公共的、公用的 * static:静的、静态的、静止的 * void:空的 * main:主要的、重要的 * class:类 * system:系统、方法 * out:出现、出外 * print:打印 * eclipse:Java编程软件 ...
《Java虚拟机规范第七版 中文版》是Java语言相关的重要文献,为程序员提供了一个关于Java虚拟机(JVM)的详尽介绍和参考。以下是详细介绍Java虚拟机规范的知识点: 一、Java虚拟机规范的重要性 Java虚拟机规范是...
例如,如果你正在设计一个学生管理系统,可以创建一个`Student`类来代表学生,包含如`name`、`age`等属性和`study`、`graduate`等方法。通过继承,你可以创建`Undergraduate`和`Graduate`子类,它们具有`Student`类...