Sealyu

--- 博客已迁移至: http://www.sealyu.com/blog

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  618 随笔 :: 87 文章 :: 225 评论 :: 0 Trackbacks

Ok, your fresh new GWT user interface is ready, it works great with GWTShell's internal Tomcat and with server-side stubs, but as you compile and deploy it on your web-app there are problems.

Of course you can debug with a JavaScript debugger (Venkman or Microsoft's Script Debugger), but generated JavaScript is really complex, for people and for those unstable debuggers.

But, wait, we have a debugger, is our state-of-the-art debugger, integrated in our IDE and GWT can use it, if only you could run client into the Shell and server side into your preferred development envinroment !!!

We could deploy our web-app into the integrated Tomcat, but it's not easy to do (and an hell to mantain) and also can be that you don't want (or you can't) use Tomcat for your Web Application.

I think that everyone should do his work, so let's Google Shell do the client, and your application server run the server side code. It's not difficult, you only need to follow these few steps.

First thing do to it's a little (I promise really little and only one) change to your GWT code, so that the client will always use absolute urls for your web-app, allowing us to use the ContextPath without problems, whatever it's the relative position of your Google client inside your root context.

To do that we have to register this way the end-point of the remote service:

	endpoint.setServiceEntryPoint( GWT.getModuleBaseURL()+"/myRemoteService" );

now we must also remember to change our servlet path inside the GWT module file (*.gwt.xml) putting the complete service name at the top, in this case /mypackage.google.GWTClient:

  	<servlet path="/mypackage.google.GWTClient/myRemoteService" class="mypackage.google.server.MyRemoteServiceImpl"/>

No other change to your client side code, I promise again.

Now let's start to modify the web-app to run our services. The first thing is to include in our WEB-INF/lib the gwt-user.jar.

Unfortunately the one supplied by Google doesn't work, because it includes the javax.servlet.* classes to simplify the automatic generation of development projects.

We must strip that out (with an ANT Task obviously):

Now we can also add that to our IDE build-path.

Everything is ready to begin the configuration of our web-app, beginning with the registration of the remote service inside web.xml, remembering the module name we used in the *.gwt.xml file:

We don't have yet finished, we must also "simulate" one of the call implemented by GWTServlet, registering its path into web.xml and with the help of a JSP::

the gwt-hosted.jsp JSP it's only a simple script with a row of scriptlet that export our web-app context to the GWT client::

We did it !!!!The good thing is that we don't even have to "Compile" our JavaScript in the destination context during debug. Infact the GWT Shell callback will always call our Java classes and not the JavaScript code.

So we have together maximum flexibility on client-side project for our debugging purposes, and only at the very finish of the development cycle we will produce the JavaScript code.

Could we be in a better position as web developer ?

Now some tips about GWT's Shell:

Are we in debug mode or not ? The answer is yes, so we should configure the Shell log to a more verbose level (if you have used GWT.log in your code):

	-logLevel ERROR|WARN|INFO|TRACE|DEBUG|SPAM|ALL

We should also disable the integrated Tomcat:

	-noserver

and configure the Shell to generate JavaScript code directly inside our web-app project:

	-out <web-app-project-dir>

Also can be useful to open directly the Shell browser to our web-app at startup, simply putting the http url as the last parameter of the command line that start the Shell.

But what if all this it's not enough to solve our problems, may be because the generated JavaScript is not working fine ? Well, together with much luck, we can try to switch the generation code to DETAILED:

 -style DETAILED

and use traditional JavaScript debugging tecnique.

Integrate Google Web Toolkit with Struts/Tiles

Ok, now everything it's integrated with your web-application and you're in love with GWT. You did really a great work, a prototype that it's working fine and looks pretty. But when time comes that you must put it into your old fashioned Struts/Tiles web-application it stops working and sure you can't write everything from scratch again, but do a step after another and start with a single functionality done with GWT.

Well, I don't know you, but I suffered from this problem, but at the end, thank to some little tips, I was able to let Struts and GWT not only to live together, but to cooperate to make my application look better.

It was like having an old fashioned B&W TV Set and a new HDMI on the same bench, side by side !!!

Well, to achieve this, we have to do some simple steps:

- In web.xml add another Struts action mapping, this time it must be extension based, for instance I choosed *.gwt:

- In struts-config.xml write the new Struts action that will render the GWT page, taking care to put at the top of the path the complete GWT's module name, so that the script will be able to find internal files with no problems:

- (only if you use Tiles as view)Add a Tiles definition that will include GWT's (in my example into the body of the layout JSP):

- (if you used filters for Struts Action mapping)Update your filters so that they will be able to do their work also with the new GWT module:

That's all, the game is made.


P.S.:the same applies if you used Spring MVC.

Integrating it also with Spring/Hibernate

The life-cycle of a GWT's Service is managed by your servlet-container, because as a design choice Google opted for the portabily and simplicity of the Servlet model.
In our code this mean that our service implementations will all inherit (indirectly) from HttpServlet. This means also that to integrate them in our Spring managed container we have to play dirty. I decided to use static property inside our Google Service implementation, so that Spring will be able to assign it at startup time.
Pratically, if we want to inject something in GWT's service mypackage.google.server.MyRemoteServiceImpl's myProperty property, it's enough to declare it static:

Then to let Spring works, we also need an instance setter:

In our applicationContext.xml we can inject the myPropertyBean Bean simply with a dummy bean declaration of the GWT implementation class:

This works because at startup Spring will instantiate an instance of the MyRemoteServiceImpl class, this instance will never be used by the servlet-container, but the bean property is contained into a static variable, so every instance will have it !!!
Now, if your business bean myPropertyBean uses Hibernate and you usually use Spring's OpenSessionInViewFilter/Interceptor to manage your Session, you need a further step and use an AOP Interceptor. But we are lucky in this, because all is done by Spring out-of-the-box only with few lines of configuration::

With this configuration, if myPropertyBean is used outside a transaction scope, a new Hibernate transaction will be created and assigned to it. In our case this is also the span of the Hibernate's Session (thanks to HibernateTransactionManager). The myHibernateInterceptor will also take charge of eventually close the Session at the end of the business method.

continue here...


posted on 2010-01-15 12:05 seal 阅读(298) 评论(0)  编辑  收藏 所属分类: SpringGWT

只有注册用户登录后才能发表评论。


网站导航: