Hibernate, Spring, Google Web Toolkit – Part Four
A few people have now requested the final step in the tutorial – making the application a true web app and how to setup the web.xml etc.
So thought it time to pull my finger out of my … and get it done.
This tutorial is based upon the previous tutorials in this work and is performed using Tomcat version 5.5. I think other tomcat versions should matter but dont quote me on that.
Firstly my sample context is as follows:
<Context path="/theproject" docBase="/Users/james/Documents/workspace/TheProject" debug="0" workDir="/Users/james/Documents/workspace/TheProjectWorkDir" reloadable="true" crossContext="true" > <Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_theproject_log." suffix=".txt" timestamp="true" /> </Context>
Thats stuff most should be comfortable with. On my setup I place my context file in CATALINA_HOME/conf/Catalina/localhost/
The next step is to compile up our GWT it Javascript.
Run your GWT application in hosted mode.
Then when ready click ‘Compile’ on the GWT hosted mode browser. If you have the same launch/compile/shell scripts as the ones I defined in Part Two of the tutorial then you should get a new folder within your project titled ‘www’.
The next step is to make your web.xml and put it in the location /WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" > <display-name>The Project</display-name> <servlet> <servlet-name>theproject</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>theproject</servlet-name> <url-pattern>*.page</url-pattern> </servlet-mapping> <!-- GWT Servlets --> <servlet> <servlet-name>teachers</servlet-name> <servlet-class>com.company.server.gwt.TeacherServiceImpl</servlet-class> </servlet> <servlet-mapping> <servlet-name>teachers</servlet-name> <url-pattern>/www/com.company.MyApplication/teachers</url-pattern> </servlet-mapping> <context-param> <param-name>webAppRootKey</param-name> <param-value>theproject.root</param-value> </context-param> <session-config> <session-timeout>45</session-timeout> </session-config> <!-- The Usual Welcome File List --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
A few important points in the web.xml are firtly notice the spring elements and I’m mapping anything with .page to go through my Spring controller.
Then also notice the GWT mappings – we’re using the url of teachers as defined in our RPC’s and pointing this at that www folder we made!! Easy so far!
Next we need to make the Spring servlet that handles the Spring controllers for sending back to the user a view. The name of the file is very important mine is called theproject-servlet.xml because this is the name used in my web.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans classpath:spring-beans-2.0.xsd http://www.springframework.org/schema/tx classpath:spring-tx-2.0.xsd http://www.springframework.org/schema/aop classpath:spring-aop-2.0.xsd"> <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"> <property name="definitions"> <list> <value>/WEB-INF/tiles-defs/templates.xml</value> </list> </property> </bean> <!-- no 'id' required, HandlerMapping beans are automatically detected by the DispatcherServlet --> <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <value> /**/help.page=simpleViewController /home.page=homepageController </value> </property> </bean> <!-- List of controllers for the application --> <bean id="simpleViewController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"> </bean> <bean id="homepageController" class="com.company.server.web.controlle.HomepageController"> <property name="successView" value="home.tile"/> <property name="exceptionView" value="exception.tile"/> </bean> <!-- Convention based ViewResolver for Tiles2 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/> </bean> </beans>
A few more important parts here – firstly the definition of a tiles file. Those familar with tiles should understand this. This is where we shall define all our pages. Secondly you can see our mappings – in this case home.page. They are handled by controllers. Notice the controller homepageController we’ll go ahead and define that class now:
Firstly in good Object oriented design we can make an abstract controller that all our controllers can extends for ease.
package com.company.server.web.controller; import org.springframework.web.servlet.mvc.BaseCommandController; public abstract class ParameterisedViewCommandController extends BaseCommandController { private String successView = null; private String exceptionView = null; /** * @return the successView */ protected String getSuccessView () { return successView; } /** * @param successView the successView to set */ public void setSuccessView ( String successView ) { this.successView = successView; } /** * @return the exceptionView */ protected String getExceptionView () { return exceptionView; } /** * @param exceptionView the exceptionView to set */ public void setExceptionView ( String exceptionView ) { this.exceptionView = exceptionView; } }
Notice the basic strings exception and success view that we defined in our servlet.xml file.
Next just the basic implementation of our defined HomepageController.
package com.company.server.web.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; public class HomepageController extends ParameterisedViewCommandController { @Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView(getSuccessView()); } }
In this case we just return a new view of the success view but you can obviously return various views. Also those familiar with struts actions the classes above are basically those.
Now go ahead and make the tiles files defined in the servlet. Create a file as specified in location /WEB-INF/tiles-def/templates.xml and in here we can define our templates. Mine if below:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://tiles.apache.org/dtds/tiles-config_2_0.dtd"> <tiles-definitions> <definition name="home.tile" template="/pages/home.jsp"> <put-attribute name="title" value="The Project" /> <put-attribute name="gwtjs" value="/theproject/www/com.company.MyApplication/com.company.MyApplication.nocache.js" /> </definition> </tiles-definitions>
The tile definition probably needs some explaing. Firstly I’m using JSTL to do my various important inserts such as the title of the page and the insert of my GWT compiled up javascript. Again still referencing that www folder and our javascript.
Right the final step is to make that page so make a folder in the root of your project called pages and make a file called home.jsp.
My page is below:
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title><tiles:getAsString name="title" /></title> <!-- Include the GWT Javascript --> <script language='javascript' src='<tiles:getAsString name="gwtjs" />'></script> </head> <body> <h1>MyApplication</h1> <p> Example GWT application calling RPC calls </p> <div id="database"></div> </body> </html>
The important areas of the page are firstly the tiles inserts – where we insert of GWT javascript and also the content of the page between the body tags. The HTML is basically exactly the same as the hosted page. Our application looks for a “database” div to replace and such this element needs to be on the page!!
That should wrap everything up now! Also as I have migrated across to the latest versions of struts/spring/tiles etc you can download a copy of my lib directory so that the above tutorial should work.
Any questions please post a comment!