Ans) Honest answer is, Yes its worth trying out.
Let me try to justify my answer
- GWT helps to develop and debug AJAX(i will talk more about ajax some other day) support web applications using standard java language.
- GWT takes a different approach on workload distribution. Traditionally, most of the heavy lifting of web application is done on server side. Google identified that some of it could be done on client side. This leaves servers to allocate more resources for business logic processing.
- Goodle has spend lot of time and resources into it and came up with its GWT compiler that seamlessly translates your java code into javascript and HTML that most browsers understand.
- As we code using java, first thing that comes in to mind is re usability of code. GWT is great at write once use any where. You can create a GWT Component(widgets) and use them across the application. If its generic enough you could also use across your company(i mean on any other GWT based projects in your organization) or even make it public, so that others can use.
I personally like eclipse and been using it in all my projects. There are some great GWT plugin's available for Eclipse that will ease your development.I use Google Plugin for Eclipse and you can get it here.
Once you have plugin succesfully installed, Create a new Web Application Project in eclipse. Go to File-> New -> Web Application Project. I am going to name it as AssetTracking.
If you dont fancy using plugin, You can manually download and install gwt on your local system from this Location. GWT ships with a command line utility called
webAppCreator
that automatically generates all the files you'll need in order to start a GWT project. It also generates Eclipse project files and launch config files for easy hosted mode debuggingwebAppCreator -out AssetTracking com.assetTracking.AssetTrackingOnce you have your project created, you can import it in to eclipse. Above command will also create a sample application which you can ignore. What we really need is the ant's build.xml that gets created, i will explain its use later.
Let me first show you the folder structure and list of files you will be needing at a minimum for creating and using a GWT Module.
AssetTracking/src/com/gwtbasics/assetTracking/AssetTracking.gwt.xml
AssetTracking/src/com/gwtbasics/assetTracking/client/AssetService.java
AssetTracking/src/com/gwtbasics/assetTracking/client/AssetServiceAsync.java
AssetTracking/src/com/gwtbasics/assetTracking/client/AssetTracking.java
AssetTracking/src/com/gwtbasics/assetTracking/server/AssetServiceImpl.java
AssetTracking/war/AssetTracking.html
AssetTracking/war/WEB-INF/web.xml
Start by creating Service Interfaces and their implementation classes.
- Create a service interface that lists out all server side calls that are needed. Lets have one call for now, that will fetch asset name for given ID. Some thing like public String getAssetAsString(String id).
AssetService interface will look like this.
package com.gwtbasics.assetTracking.client;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
/**
* The client side stub for the RPC service.
*/
@RemoteServiceRelativePath("asset")
public interface AssetService extends RemoteService {
public String getAssetAsString(String id);
} - AssetService.java is our client side stub. For server side implementation in RPC you will create AssetServiceImpl.java and it should extend RemoteServiceServlet and implements AssetService
package com.gwtbasics.assetTracking.server;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.gwtbasics.assetTracking.client.AssetService;
/**
* The server side implementation of the RPC service.
*/
@SuppressWarnings("serial")
public class AssetServiceImpl extends RemoteServiceServlet implements
AssetService {
public String getAssetAsString(String input) {
return "Asset Name for id="+input+" is USPS Whale Shipment";
}
} - We now have client side stub as AssetService.java, Server side implementation as AssetServiceImpl.java. All we need now is a client side Async handler. This would be AssetServiceAsync.java and it would look like this.
package com.gwtbasics.assetTracking.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
/**
* The async counterpart ofAssetServiceAsync
.
*/
public interface AssetServiceAsync {
void getAssetAsString(String input, AsyncCallbackcallback);
} getAssetAsString(String input, AsyncCallback
Give a close look at thecallback) method declaration and compare with getAssetAsString of AssetService.java. i am sure you will notice some difference.
package com.gwtbasics.assetTracking.client;Next comes the AssetTracking.gwt.xml , This is a GWT module configuration file. In this you can tell where you are inheriting from and what the entry point class is.
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
/**
* Entry point classes defineonModuleLoad()
.
*/
public class AssetTracking implements EntryPoint {
/**
* The message displayed to the user when the server cannot be reached or
* returns an error.
*/
private static final String SERVER_ERROR = "An error occurred while "
+ "attempting to contact the server. Please check your network "
+ "connection and try again.";
/**
* Create a remote service proxy to talk to the server-side Asset service.
*/
private final AssetServiceAsync greetingService = GWT
.create(AssetService.class);
/**
* This is the entry point method.
*/
public void onModuleLoad() {
final Button sendButton = new Button("Send");
final TextBox nameField = new TextBox();
nameField.setText("GWT User");
// We can add style names to widgets
sendButton.addStyleName("sendButton");
// Add the nameField and sendButton to the RootPanel
// Use RootPanel.get() to get the entire body element
RootPanel.get("nameFieldContainer").add(nameField);
RootPanel.get("sendButtonContainer").add(sendButton);
// Focus the cursor on the name field when the app loads
nameField.setFocus(true);
nameField.selectAll();
// Create the popup dialog box
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Remote Procedure Call");
dialogBox.setAnimationEnabled(true);
final Button closeButton = new Button("Close");
// We can set the id of a widget by accessing its Element
closeButton.getElement().setId("closeButton");
final Label textToServerLabel = new Label();
final HTML serverResponseLabel = new HTML();
VerticalPanel dialogVPanel = new VerticalPanel();
dialogVPanel.addStyleName("dialogVPanel");
dialogVPanel.add(new HTML("Sending id to the server:"));
dialogVPanel.add(textToServerLabel);
dialogVPanel.add(new HTML("
Server replies:"));
dialogVPanel.add(serverResponseLabel);
dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
dialogVPanel.add(closeButton);
dialogBox.setWidget(dialogVPanel);
// Add a handler to close the DialogBox
closeButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
dialogBox.hide();
sendButton.setEnabled(true);
sendButton.setFocus(true);
}
});
// Create a handler for the sendButton and nameField
class MyHandler implements ClickHandler, KeyUpHandler {
/**
* Fired when the user clicks on the sendButton.
*/
public void onClick(ClickEvent event) {
sendNameToServer();
}
/**
* Fired when the user types in the nameField.
*/
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
sendNameToServer();
}
}
/**
* Send the name from the nameField to the server and wait for a response.
*/
private void sendNameToServer() {
sendButton.setEnabled(false);
String textToServer = nameField.getText();
textToServerLabel.setText(textToServer);
serverResponseLabel.setText("");
greetingService.getAssetAsString(textToServer,
new AsyncCallback() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
dialogBox
.setText("Remote Procedure Call - Failure");
serverResponseLabel
.addStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(SERVER_ERROR);
dialogBox.center();
closeButton.setFocus(true);
}
public void onSuccess(String result) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel
.removeStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(result);
dialogBox.center();
closeButton.setFocus(true);
}
});
}
}
// Add a handler to send the name to the server
MyHandler handler = new MyHandler();
sendButton.addClickHandler(handler);
nameField.addKeyUpHandler(handler);
}
}
Here are some of the Tags that are important.
- inherits name='com.google.gwt.user.User' --- (This tells where your current hirarchy is extending from. similar to class extension in java)
- entry-point class='com.gwtbasics.assettracking.client.AssetTracking' --- (This tells what is the entry point for your gwt, first class that gets invoked. Any class mentioned here should extend from com.google.gwt.core.client.EntryPoint)
<?xml version="1.0" encoding="UTF-8"?>
<DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd">
<module rename-to='assettracking'>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Inherit the default GWT style sheet. You can change -->
<!-- the theme of your GWT application by uncommenting -->
<!-- any one of the following lines. -->
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
<!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
<!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/> -->
<!-- Other module inherits -->
<!-- Specify the app entry point class. -->
<entry-point class='com.gwtbasics.assetTracking.client.AssetTracking'/>
</module>
Now lets go ahead and write our html file and use above created module.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">Lets write our last bit of code. Its the web.xml file that has our AssetService and appropriate servlet mappings.
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type="text/css">
/** Add css rules here for your application. */
/** Example rules used by the template application (remove for your app) */
h1 {
font-size: 2em;
font-weight: bold;
color: #777777;
margin: 40px 0px 70px;
text-align: center;
}
.sendButton {
display: block;
font-size: 16pt;
}
/** Most GWT widgets already have a style name defined */
.gwt-DialogBox {
width: 400px;
}
.dialogVPanel {
margin: 5px;
}
.serverResponseLabelError {
color: red;
}
/** Set ids using widget.getElement().setId("idOfElement") */
#closeButton {
margin: 15px 6px 6px;
}
</style>
<title>Asset Tracking Sample Project Using GWT</title>
<!-- -->
<!-- This script loads your compiled module. -->
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<!-- -->
<script type="text/javascript" language="javascript" src="assettracking/assettracking.nocache.js"></script>
</head>
<body>
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
<h1>Asset Tracking Sample Project Using GWT</h1>
<table align="center">
<tr>
<td colspan="2" style="font-weight:bold;">Please enter your name:</td>
</tr>
<tr>
<td id="nameFieldContainer">
<td id="sendButtonContainer">
</tr>
</table>
</body>
</html>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Servlets -->
<servlet>
<servlet-name>assetServlet
<servlet-class>com.gwtbasics.assetTracking.server.AssetServiceImpl
</servlet>
<servlet-mapping>
<servlet-name>assetServlet
<url-pattern>/assettracking/asset
</servlet-mapping>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>AssetTracking.html
</welcome-file-list>
</web-app>
Here we created full set of files for our first GWT application.
So how do we compile and run this thing? Easy i say...
If you are using Google Plugin for Eclipse, just right click on the project and run/debug as Web Application and you will see the result.
But if you have generated your application through webAppCreator, you can use ant build.xml to execute. You need to execute hosted ant task to invoke your app in hosted mode.
I hope you were able to successfully create your first web app using GWT and enjoied it.
Please stay tuned to my blog for more advanced topics on GWT.
nice and interesting basics,really useful and one can learn a lot from it,this is really useful adn informative and can guide many people
ReplyDelete