虽然GWT充满了争议,但是对于Java开发者而言,能够使用自己最熟悉的语言来进行Ajax开发,Google推出的GWT的确具有相当大的诱惑力,而且作为一个快速发展的开源框架,相信以后它的用户群应该会越来越多。
Jetty Continuations 很好的解决了服务器更新客户端的问题,服务器不用再为每一个等待响应的客户端单独建立一个线程,借助Continuations和新IO,可以在有限的线程内支持更多用户。
更多内容参见
http://docs.codehaus.org/display/JETTY/Continuations
最近在做一个浏览器上的在线聊天项目,用来做为在线客服支持,打算使用GWT编写界面,但是GWT所提供RPC机制并不直接支持Jetty Continuations。为了支持比当前线程数更多的用户,Jetty中的Continuation.suspend()会抛出一个特殊的运行时异常:RetryRequest。这个异常将传播到servlet以外,然后通过过滤器传回,再由SelectChannelConnector捕获,将请求放入处于等待状态的Continuation队列中,此时HTTP连接并不关闭,而当前的线程却可以被放回线程池,供别的请求使用。但是使用GWT时,GWT捕获了所有的Throwable,这样就会导致Continuations机制失败。而且GWT提供的RemoteServiceServlet类中很多方法都被定义为final或static,于是你无法通过继承这个类来重写相关方法,让它放过RetryRequest。
但是因为GWT是开源项目,于是Jetty组织改写RemoteServiceServlet,提供了OpenRemoteServiceServlet,将Continuations所敏感的方法去掉final和static,然后继承OpenRemoteServiceServlet,提供了它们自己的AsyncRemoteServiceServlet,这样我们GWT服务器端的RPC接口的实现类直接继承AsyncRemoteServiceServlet,无须其它更改,就可以使用Jetty Continuations的API了。
AsyncRemoteServiceServlet14.java中放过RetryRequest的相关代码:
/**
* Throws the Jetty RetryRequest if found.
*
* @param caught the exception
*/
protected void throwIfRetyRequest(Throwable caught) {
if (caught instanceof UnexpectedException) {
caught = caught.getCause();
}
if (caught instanceof RuntimeException && JETTY_RETRY_REQUEST_EXCEPTION.equals(caught.getClass().getName())) {
throw (RuntimeException) caught;
}
}
更多内容参见
http://blogs.webtide.com/gregw/2006/12/07/1165517549286.html
这里提供一个完整的小例子给大家,也作为我这段时间学习的总结
:
下载最新的
GWT
http://code.google.com/webtoolkit/download.html
Jetty
http://docs.codehaus.org/display/JETTY/Downloading+and+Installing#download
然后在
http://jira.codehaus.org/browse/JETTY-399上面找到OpenRemoteServiceServlet14.java和AsyncRemoteServiceServlet14.java,这是OpenRemoteServiceServlet和AsyncRemoteServiceServlet的新版本,支持GWT1.4版本。
首先使用GWT的命令行工具创建eclipse下的GWT项目,然后导入到eclipse中,再导入jetty-util-6.1.3.jar。
RPC接口定义:
public interface TestService extends RemoteService {
public String getNews();
}
GWT的入口类:
public class GCEntry implements EntryPoint {
public void onModuleLoad() {
final TestServiceAsync testService = (TestServiceAsync)GWT.create(TestService.class);
ServiceDefTarget target = (ServiceDefTarget)testService;
target.setServiceEntryPoint(GWT.getModuleBaseURL() + "test");
final TextArea printArea = new TextArea();
printArea.setVisibleLines(10);
printArea.setCharacterWidth(30);
testService.getNews(new AsyncCallback() {
public void onFailure(Throwable caught) { }
public void onSuccess(Object result) {
printArea.setText(printArea.getText() + result);
testService.getNews(this);
}
});
DockPanel dp = new DockPanel();
dp.add(printArea, DockPanel.CENTER);
RootPanel.get().add(dp);
}
}
界面将显示一个文本框,反复调用testService.getNews(),将异步返回的结果输出到文本框中。
服务器端RPC接口的实现:
public class TestServiceImpl extends AsyncRemoteServiceServlet14 implements
TestService {
private NewsCreator newsCreator;
public void init() {
newsCreator = new NewsCreator();
}
public String getNews() {
return newsCreator.getNews(getThreadLocalRequest());
}
}
注意这里继承的是AsyncRemoteServiceServlet14。通过一个辅助类NewsCreator来生成新的时间:
public class NewsCreator implements Runnable {
private Set<Continuation> readers;
public NewsCreator() {
readers = new HashSet<Continuation>();
new Thread(this).start();
}
public void run() {
while (true) {
synchronized(this) {
for (Continuation continuation : readers) {
continuation.setObject(new Date().toString() + "\r\n");
continuation.resume();
}
readers.clear();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public String getNews(HttpServletRequest request) {
Continuation continuation = ContinuationSupport.getContinuation(request, null);
synchronized(this) {
readers.add(continuation);
}
continuation.suspend(10000);
String news = continuation.getObject() == null ? "No Time" : (String)continuation.getObject();
continuation.setObject(null);
return news;
}
}
getNews()为每个请求获取一个Continuation实例,然后将这个实例保存起来,阻塞10秒,同时NewsCreator每隔两秒发布一次时间,发布时将当前时间附在Continuation上,恢复被阻塞的Continuation。Continuation在被恢复或超时之后相对应的请求都会被重新执行,当再次执行到Continuation.suspend()时,这个方法会马上返回,然后继续执行suspend()后面的代码,返回上一次发布的时间或是"No Time",当然这里发布的间隔比阻塞的时间小,不会出现"No Time"。
完整代码见附件
分享到:
相关推荐
【GWT与Spring整合】是现代企业级应用开发中的一个重要话题。Google Web Toolkit (GWT) 是一个由Google开发的开源工具包,它允许开发者使用Java编写富互联网应用(RIA),然后自动将其编译为高效的JavaScript代码。...
总的来说,整合Liferay与GWT可以使开发者利用Liferay的门户功能和GWT的富客户端开发能力,创建出既美观又高效的Web应用。通过理解上述步骤,并根据具体的项目需求进行调整,开发者可以更好地实现这种整合,提高工作...
如果这里的"ssh"是指安全套接层(Secure Shell),那么它可能与远程管理和部署有关,但与GWT和Spring的整合不太直接相关。 现在,我们来看看压缩包内的各个子文件: 1. **springgwt.tar.gz** - 这可能是一个包含...
JAVA整合GWT框架,利用ITEXT插件,实现从SQL2008中导出数据到已有的模板中。资源里附有PDF模板,构建PDF模板的WORD文件,以及PDF模板所要做成PDF文件的图片式样。该资源还实现了导出SQL2008某行某列的数据到PDF模板...
3. **GWT与Tomcat的整合**: - 集成GWT应用程序到Tomcat,首先需要确保Tomcat服务器已经正确安装并配置好。 - 开发者通常会使用GWT的开发模式,通过内置的HTTP服务器进行本地调试。一旦准备好,需要将编译后的GWT...
Spring与GWT结合,可以在服务器端处理业务逻辑,通过GWT的Remote Procedure Call (RPC)机制与客户端进行通信。 3. **Hibernate ORM**: Hibernate 是一个流行的Java ORM(对象关系映射)框架,它允许开发者用Java...
标题中的" GWT整合Hibernate的一个小实例 "是指将Google Web Toolkit(一种用于创建富客户端Web应用的Java开发框架)与Hibernate(一个流行的对象关系映射(ORM)框架)结合使用,以便在GWT应用中执行数据库交互。...
SmartGwt、Mybatis与Spring的整合是企业级Java应用开发中的常见技术栈组合,这三种框架各有其专长,可以高效地构建出强大的后台系统。SmartGwt是一款基于GWT(Google Web Toolkit)的开源UI组件库,提供丰富的用户...
- **下载与安装**:首先需要下载GWT SDK,然后在MyEclipse中进行添加。这通常涉及在"Window" -> "Preferences" -> "Google" -> "Web Toolkit"中点击"Add",选择GWT SDK的安装路径。 - **创建GWT项目**:创建一个新...
尽管相对于其他组合,GWT与Spring的整合资料可能较少且版本较旧,但依然有重要的实践价值。 首先,整合GWT和Spring的主要目标是利用GWT的客户端功能和Spring的服务器端能力。这通常涉及以下步骤: 1. **配置Spring...
总的来说,GWTEXT 与Hibernate的整合实例是一个典型的Java企业级应用开发场景,它结合了文本处理的强大功能和数据库操作的便利性,对于处理大量文本数据的企业应用具有很高的实用价值。通过这个实例,开发者可以深入...
本项目"smartGwt、spring、Mybatis整合"就是一个很好的例子,它将三种流行的技术——SmartGWT、Spring和Mybatis融合在一起,创建了一个包含登录功能和分页查询功能的应用。以下是关于这三个技术及其整合方式的详细...
【GWT整合Spring】是指将Google Web Toolkit (GWT) 应用程序与Spring框架集成,以便利用Spring的强大功能,如依赖注入、事务管理、安全控制等。GWT 是一个用于构建高性能、富客户端Web应用的Java开发工具,而Spring...
标题 "Ext-Gwt(GWT)开发实例(整合Spring +Hibernate)" 涉及到的是一个实际项目开发的教程,其中结合了三个重要的技术框架:Google Web Toolkit (GWT),Spring 和 Hibernate。这个实例旨在展示如何在Web应用开发中...
学习如何将GWT应用打包成WAR文件,然后部署到Web服务器,如Tomcat或Jetty,是实际项目开发的必要步骤。 通过实例解析源码,你可以看到这些概念如何在实际项目中应用,例如创建一个简单的登录注册系统、实现数据...
总的来说,Struts2与GWT的整合使得开发者能够利用Struts2的强大后端能力与GWT的高效前端表现,构建出功能强大且用户体验优秀的Web应用。但需要注意的是,这种整合也需要开发者对两者的深入理解和良好的架构设计,以...
1. **GWT SDK安装与设置**:首先,你需要下载并安装GWT SDK,配置IDE(如Eclipse或IntelliJ IDEA)以支持GWT项目开发。 2. **模块化(GWT Module)**:每个GWT项目都始于一个`.gwt.xml`模块文件,它定义了项目的...
GWT,全称为Google Web Toolkit,是Google推出的一款开源JavaScript开发框架,允许Java开发者使用Java语言来编写Web应用。...在实际学习过程中,应结合实际项目需求,理论与实践相结合,以达到最佳的学习效果。