(AJAX) - HTML/JavaScript/Servlet
by Jean-Marc Autexier,
11/13/2005
Introduction
This page shows how to create asynchronous http requests from web page, process it in a servlet and update the page without reloading it. Data's are not yet transfered as XML, so it's not AJAX (next version will be), but other Web2.0 stuff is shown: asynchronous http requests, javascript, DOM, servlet.
Environment
To run the example, you need a recent browser able to send http request objects (recent firefox, konqueror, Internet explorer are ok) and a servlet runtime. I use jetty for it as it is very simple to install, fast and easy to use. I like to have full control over the engine, so I embed it into my own application (see ServletMain.java). I'm starting a http server on port 8080, add a servlet handler (servlets URL will be "/myServlet") and a static HTML context (which just delivers HTML pages located in "./html" directory).
24 HttpServer server = new HttpServer();
25 server.addListener(":8080");
26
27 // Servelts
28 HttpContext context = server.getContext("/");
29 ServletHandler handler= new ServletHandler();
30 handler.addServlet("MyServlet","/myServlet/*", "servlet.TestServlet");
31 context.addHandler(handler);
32
33 // Static HTML pages: files in html are directly in "/"
34 HttpContext htmlContext = new HttpContext();
35 htmlContext.setContextPath("/");
36 htmlContext.setResourceBase("./html/");
37 htmlContext.addHandler(new ResourceHandler());
38 server.addContext(htmlContext);
The web page
Let's start first with the web page, and come back to the server later. The sample application will be a very small chat MMI. One can send messages to the server and the chat will be updated on the same page. The full html page can be found in sample1.html.
Here what it does:
First, we need a httpRequester object. It will be used to send asynchronous messages to the server. As this part is browser dependent, we will initiate it at the beginning so we don't have to care about it later.
var httpRequester = getHTTPRequestObject(); // Create the xml http object on the page loadThe body just consist of 3 elements:
<!-- retrieve browser dependent httpRequest processor -->
function getHTTPRequestObject() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
else {
alert("No http request object found!!");
}
}
1. a message element. it's empty at the beginning and it will be used to display received messages
2. an input field (id="text") where the use can enter the text
3. a button which sends the text to the server (using a JavaScript method).
<p>Messages:</p>
<div id="chatlog"></div>
<p>
Your Message:
<input id="text"/>
<input type="button" value="Send" onclick="sendMessage()"/>
</p>
The function sendMessage is very simple: it retrieves the content of the text field, and open a connection to the sever using the httpRequester object mentioned above. There are 3 parameters: the first one indicates if the request is POST or GET, the next one contains the servlet ("./myServlet)) and parameters ("?text="+text). The last is used to send asynchronous or synchronous http request. We will send asynchronous messages. As we send an asynchronous message, we have to define a callback function (processResponse) which will be called when a message for this request comes back.
function sendMessage() {
var text = document.getElementById("text").value;
if (httpRequester)
{
httpRequester.open("POST", "./myServlet?text="+text, true);
<!-- bind processResponse as response to this request -->
httpRequester.onreadystatechange = processResponse;
httpRequester.send(null);
}
}
The callback funtion is called by the browser when receives an answer
to the request. In complex scenarios, several asynchronous requests can
be send in parallel. To register different response processors allows
to handle each response with the correct processor.The processor first check the state of the response. 4 means that the request has been completed and the answer is available. Here, the httpRequester object contains the returned String in ".responseText" attribute. We extract it and set the value of the "chatlog" object to it. In case you receive back an text/XML response, one can use httpRequester.getElementsByTagName() XML parser.
function processResponse() {
if ( httpRequester.readyState == 4 ) { // 4 means complete
var values = httpRequester.responseText; // parse the server response
document.getElementById("chatlog").innerHTML = values;
// remark: for text/XML, the response XML object can be accessed using
// httpRequester.getElementsByTagName()
}
}
The servlet
The servlet is the simple part. I will not explain internal helper classes (Message, Chat) of TestServlet.java, but only what is related to the communication.
The servlet adds the received text from the parameter "text" to the chat object. Then it retrieves all messages from the chat, build a HTML String and send it back. That's it, no magic here.
27 public void doGet(HttpServletRequest sreq, HttpServletResponse sres) {(For real AJAX, we would have build a XML document and used on client side the getElementByTagName() method (or even better, we just send changed messages and not all)).
28
29 // add the new message to the chat
30 chat.addMessage(sreq.getParameter("text"));
31
32 // build current chat from all messages
33 List messages = chat.getMessages();
34 StringBuilder sb = new StringBuilder();
35 for (int i=0;i<messages.size();i++) {
36 Message msg = (Message)messages.get(i);
37 sb.append(formatter.format(msg.getArrival())).append(" : ").append(msg.getMessage());
38 }
39
40 try {
41
42 sres.getOutputStream().println(sb.toString());
43 } catch (IOException ex) {
44 ex.printStackTrace();
45 }
46 }
Have fun with Web2.0/AJAX (I don't think it will ever replace native apllications, but it's interesting to see what is possible. Microsoft, Yahoo Google and other have quite impressive applications build with this tehcnologie (and DHTML, CSS, ...).