Montag, 30. November 2009

How to use GWT with PHP

To use PHP on the server side in combination with a GWT client-application makes a lot of sense, since most inexpensive webhosting solutions permit you at least to run PHP on their machines. In this tutorial I demonstrate the basic steps for calling a PHP script from a GWT application using HTTP GET.

A quick look at the finished application

The finished "masterpiece" will look like this. You enter the URL + GET parameters of your PHP script in the inputField. Click "submit" and the application will display the server's response.




As described here the "Same Origin Policy" requires the PHP script to reside on the same server where your GWT code is. To develop your application on your local computer you probably have to start with the installation of a local webserver.

Step one: Install a local Apache web server

In order to run PHP code on your local machine it makes sense to install a local development server as described in this tutorial. This is just a matter of minutes if you use the pre-configured XAMPP package as suggested in the tutorial.

Step two: write a PHP script that processes your request on the server side

For testing purposes I use this small PHP script that will simply echo out the input it receives to the sender.

<?php
echo "The following values have been received by test.php:\n";
foreach ($_GET as $key=>$value) {
echo "GET KEY: $key GET VALUE: $value\n";
}

foreach ($_POST as $key=> $value) {
echo "POST KEY: $key POST VALUE: $value\n";
}
?>



Save this script under the name "test.php" in your XAMPP htdocs-directory. As described in the previous tutorial, you need also to copy some GWT-files to the htdocs-directory to be able to run your application in hosted mode. Your htdocs-directory should contain the following files:


HelloWorld.css
HelloWorld.html
test.php
helloworld\hosted.html
helloworld\helloworld.nocache.js



Step three: Tell GWT to use HTTP

In order to be able to use the HTTP-methods in GWT you have to include the following line of code to your module-xml file (HelloWorld.gwt.xml). See this tutorial for details.


<inherits name="com.google.gwt.http.HTTP"/>




Step four: Create your entry point method "onModuleLoad" and some global widgets



public TextArea inputField = new TextArea();
public TextArea outputField = new TextArea();
public VerticalPanel vPanel = new VerticalPanel();


/**
* This is the entry point method.
*/
public void onModuleLoad() {

Button submitButton = new Button("Submit");

inputField.setText("http://localhost/test.php?");
inputField.setSize("600px", "75px");
outputField.setSize("600px", "200px");

// Button click handler. Calls the server query
submitButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
doGet(inputField.getText());
}
}); // submitButton clickHandler

// add some widgets to the user interface.
vPanel.add(new Label("Enter your URL here:"));
vPanel.add(inputField);
vPanel.add(submitButton);
vPanel.add(new Label("Server response:"));
vPanel.add(outputField);
RootPanel.get().add(vPanel);
}




Step five: Create the method that processes the server response

When firing a server query you need to process the server's response asynchronously since it would be a bad idea to freeze the application until the response has arrived. This is done in "doGet" with a RequestCallback object whose "onResponseReceived" method is executed by the time the response arrives. "onResponseReceived" then calls my own method (processResponse) to which it passes the response-string it received (the output of the PHP script). "processResponse" is very simple: It just displays the server's response in the "outputField".


public void processResponse(String responseString) {
outputField.setText(responseString);
} // processResponse



Step six: Create the method that fires the GET-request

This method does the actual work. It calls the url you have enterd in the inputField and creates a callback object whose "onResponseReceived" method is executed by the time the response arrives. This method calls "processResponse" shown above and passes on the returned string.


public void doGet(String myurl) {
// make sure spaces and special characters have the correct encoding
myurl = URL.encode(myurl);

RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, myurl );

try {
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
processResponse("ERROR. Could not connect to server.");
}

public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
// call the method in main class to process the response
processResponse(response.getText());
} else {
processResponse("ERROR. Errorcode: " + response.getStatusCode());
}
}
});

} catch (RequestException e) {
processResponse("ERROR. No connection to server");
}
}



Using the application

To use the application simply add your GET-values to the URL that calls your PHP script. The format of the call must be: key=value&key2=value2


http://localhost/test.php?myname=John&mylastname=Smith

Sonntag, 29. November 2009

How to use a local apache webserver with GWT

OK, why would you want to do this?

Calling a PHP or Perl script from your GWT application can be a real challenge since the local webserver used by GWT (Jetty) is by default not able to execute scripts. Placing the script on a remote server where PHP can be executed is not an option, since that collides with your browser's Same Origin Policy. This security mechanism requires that your script is located at the same location where your GWT code resides.

So if you want to combine GWT with PHP or perl(python? ...) and still develop and test your GWT application locally, you have to be able to run scripts on your local machine.

The easiest way to do this, is to replace the GWT built-in jetty server with a pre-configured local webserver package. I am sure there is also a way to tell jetty how to read PHP, but if you don't need any server-side java, it's easier to use apache.

Step one: Install the local web server
First you have to download and install a local webserver. I recommend that you use the XAMPP-package which bundles a web server, MySQL, PHP and a lot more. The installation is quick and they have versions for Windows, OSX, Linux and Solaris. I chose the "light" version since it included all the tools I needed for the beginning.

Check if the local webserver is up and running by calling "http://localhost" from your browser. The XAMPP startpage should open up.

If you don't have a server-response on "http://localhost", make sure that the local webserver has actually been started. Start the XAMPP control panel application and check if apache is running.




Step two: Create the server directory structure
You need to copy a couple of files from your Eclipse workspace to the XAMPP server home-directory for hosted mode browsing to work.

My server-home directory looks like this:

HelloWorld.css
HelloWorld.html
helloworld\hosted.html
helloworld\helloworld.nocache.js


Check the script-tag in your HTML host page (HelloWorld.html) for the correct name and path of your *.nocache.js file.


<script type="text/javascript" language="javascript"

src
="helloworld/helloworld.nocache.js"></script>



Step three: Tell GWT to use the local webserver
In order to have GWT actually use the local webserver you have to make some modifications in your Eclipse run-configuration. Right-click on your "HelloWorld" project in Eclipse and choose "Run As -> Run Configurations".



In the run configuration editor choose your "HelloWorld" application from the "Web Application" section on the left. Select the "Main" tab on the right side of the editor. Deselect the checkbox "Run built-in server" and change the port to 80.



That's it. If you start your GWT application, you can see in the hosted mode url-bar that it is served by apache (port 80 on localhost). Your GWT app now can use any script that is located on your local web server.


A note on security
A local webserver behaves like a "real" webserver. This means that your machine can be contacted on port 80 from the outside. Usually this port is blocked by your DSL or cable modem but in order to make sure, you might want to run a web-based portscan that checks for open ports on your computer. If in doubt: shut apache down!

Samstag, 28. November 2009

GWT configuration files and project organization

In this post I show you the very basics of file organization in a GWT project. A comprehensive overview covering all aspects of project organization can be found on the main GWT page.


A GWT project consists of at least three files (you usually have a lot more but these are essential):

  1. a module XML file telling GWT where to find its properties.

  2. an entry point class (this is the .java class with the "onModuleLoad" method).

  3. a HTML host page that is called from the browser to start your application.


If you generated the "HelloWorld" example as described in the previous post, your project is organized as shown below:



The module XML file
This is the main configuration file for GWT. Here you tell GWT where to find your entry point class. You define a CSS stylesheet and inherit external modules. Don't worry about the content of the file at this point.

If you double-click on the module XML file, the XML-Editor opens up by default. I use the text-editor instead. To open the XML-file with the text editor right-click on the filename in the Eclipse Project-Explorer and select "Open With -> Text Editor".



The entry point class
All of your coding starts here. This class is the main entry point of your application. It must implement the interface "EntryPoint" and has to contain the public void method "onModuleLoad()".

The HTML host page
The HTML host page is the starting point of your application. You already know that GWT compiles your java-code into JavaScript so that it can be executed by your browser. But you cannot load a JavaScript file directly into the browser. It has to be called from within an HTML file. This is exactly what the HTML host page does: bootstrapping your application.

Your GWT application is started by opening the HTML hostpage in the browser. The hostpage defines the CSS stylesheet, prints a couple of HTML elements (the headline "Web Application Starter Project") and then executes helloworld.nocache.js. This script just identifies your browser and then loads a browser specific JavaScript file with your application.

A very simple "Hello World" example

Usually introductory books start with a "Hello World" application - one or two lines of code that print the message "Hello World" to the screen. This makes you familiar with the development environment and demonstrates how to embed your code into the larger class structure.

With GWT it's different. Google's introductory "Hello World" has not two, but more than 200 lines of code.

I believe that a "Hello World" app should demonstrate only the very basic functionality and not confuse with RPC and event handling right away. So in this post I will reduce Google's "Hello World" to the bare minimum in order to demonstrate what the core of a GWT application is.

Create your first application
Follow the instructions on the Google page for building your first web-application with the Eclipse-plugin. Name your project "HelloWorld" and the package "com.example.mywebapp". You end up with a very sophisticated "Hello World" application which we will strip down to something less complex below.

Where is main?
In GWT there is no "main" method. Program execution starts in a method named "onModuleLoad" in the class "HelloWorld". You find this class in the package "com.example.mywebapp.client".

Stripping down "HelloWorld"
Now erase all the content of the "onModuleLoad" method and replace it by the following two lines of code:

public void onModuleLoad() {
Label label = new Label("Hello World!");
RootPanel.get().add(label);
}




Right-click on the project-name in Eclipse's Project Explorer window and choose "Run As -> Web Application". Now two new windows open up. One shows the server log, the other one being your "Hosted Mode Browser" (all that will probably change in GWT 2.0). A detailed description of "Hosted Mode" can be found here.

The output of your "Hello World" program is shown on the left side of the Hosted Mode Browser window. You'll notice a lot of other stuff in the browser that seems to stem from a different source. We'll cover that later.



There can be only one webserver running at a time. If your local webserver (jetty) shows up with an error message, you probably already have a hosted mode browser open. In this case just close the window with the error message, switch to the browser and hit "Refresh".

Use GWT with the Eclipse plugin!

GWT can be downloaded as .zip-file or as part of the Eclipse-plugin. I tried both and must say that the Eclipse-plugin is much more convenient to use than the standalone version.

This page provides all the downloadlinks and has instructions on building your first application.

Make sure your books/tutorials are up to date. There are still many books on the market where the first application is created at the command prompt using tools like "applicationCreator" (this is now called "webAppCreator" and it all works completely different). In order to build your first application you better follow the instructions on the webpage mentioned above.

Skills needed to start programming GWT

What is GWT?
The Google Web Toolkit (GWT) is a collection of tools for developing Web-Applications. Your web-browser only talks HTML, JavaScript and CSS. Creating large dynamic applications with these technologies can be a real challenge. With GWT you build your application in Java and "compile" it into JavaScript which can be executed in the browser. If you know Java you can now build large dynamic web applications (almost) without knowing all the AJAX stuff.

Java
GWT apps are developed in Java. It definitely does not require many years of experience as a Java developer to start with GWT. But you should have a basic understanding of the Java-language and know how anonymous inner classes work since all the event handling uses them heavily. Check out this tutorial for more information. If you have some experience developing Swing-applications: perfect. You'll recognize many of these concepts are used in GWT.

Eclipse
Using Eclipse is the most convenient way of developing GWT apps in Windows, OSX or Linux.

With a lot of time you will probably be able to get it running in any other IDE like Netbeans, BlueJ or IntelliJ. And of course you can also use the command-line version with a text editor.

Since most folks at Google seem use Eclipse or BBEdit I think that you are best of by just doing the same in order to run into the least problems.

HTML and CSS
GWT apps are layouted using CSS and ambedded into HTML pages. Therefore you need some basic experience with CSS and HTML to get it running. The standard layout looks like - well - "basic". If you want something more advanced you have to style it yourself with CSS. Unfortunately I have not seen a comprehensive collection of good CSS examples for GWT yet. Drop me a note if you find something.
Firebug can make your life a lot easier finding the problems with CSS.

Freitag, 27. November 2009

About this blog

I discovered GWT just a few months ago. "Cool stuff" I thought and pretty easy to learn, too since all the programming is done in Java. Well - I quickly realized that GWT is getting rather complex as soon as you develop an application a little more advanced than "Hello World".

There are many reasons for that. One is surely that GWT is under constant development. There is almost no literature available that covers the current version (2.0 RC1 has just been released by the time I write this). And the documentation is often outdated. What makes things worse: for a casual Java user like me it frequently took quite long to comprehend the often very sophisticated example code provided.

Sometimes I needed a couple of hours just to find out how a piece of code or a specific technology worked. With the right advice I would have understood it right away.

In this blog I will publish my personal notes which were created in the course of me learning GWT. I hope it's of any use to you and will save you some time.

Live long and prosper!