views:

273

answers:

3

I am trying to create a web application using the MVC design pattern. For the GUI part I would like to use JavaScript. And for the controller Java Servlets.

Now I have never really worked with JavaScript, so I'm having a hard time figuring out how to call a Java Servlet from JavaScript and how to get the response from the Servlet.

Can anybody help me out?

A: 

Sorry, I read jsp not javascript. You need to do something like (note that this is a relative url and may be different depending on the url of the document this javascript is in):

document.location = 'path/to/servlet';

Where your servlet-mapping in web.xml looks something like this:

<servlet-mapping>
    <servlet-name>someServlet</servlet-name>
    <url-pattern>/path/to/servlet*</url-pattern>
</servlet-mapping>
krock
That isn't "from JavaScript"
David Dorward
Not it is from JavaScript, but that level of trivial stuff is far closer to being the controller than a view.
David Dorward
+1  A: 

I really recommend you use jquery for the javascript calls and some implementation of JSR311 like jersey for the service layer, which would delegate to your controllers.

This will help you with all the underlying logic of handling the HTTP calls and your data serialization, which is a big help.

migsho
+2  A: 

So you want to fire Ajax calls to the servlet? For that you need the XMLHttpRequest object in JavaScript. Here's a Firefox compatible example:

<script>
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            var data = xhr.responseText;
            alert(data);
        }
    }
    xhr.open('GET', 'myservlet', true);
    xhr.send(null);
</script>

This is however very verbose and not really crossbrowser compatible. For the best crossbrowser compatible way of firing ajaxical requests and traversing the HTML DOM tree, I recommend to grab jQuery. Here's a rewrite of the above in jQuery:

<script src="http://code.jquery.com/jquery-latest.min.js"&gt;&lt;/script&gt;
<script>
    $.get('myservlet', function(data) {
        alert(data);
    });
</script>

Either way, the Servlet on the server should be mapped on an url-pattern of /myservlet (you can change this to your taste) and have at least doGet() implemented and write the data to the response as follows:

String data = "Hello World!";
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(data);

This should show Hello World! in the JavaScript alert.

You can of course also use doPost(), but then you should use 'POST' in xhr.open() or use $.post() instead of $.get() in jQuery.

Then, to show the data in the HTML page, you need to manipulate the HTML DOM. For example, you have a

<div id="data"></div>

in the HTML where you'd like to display the response data, then you can do so instead of alert(data) of the 1st example:

document.getElementById("data").firstChild.nodeValue = data;

In the jQuery example you could do this in a more concise and nice way:

$('#data').text(data);

To go some steps further, you'd like to have an easy accessible data format to transfer more complex data. Common formats are XML and JSON. The last one is most preferred since it's more concise and can be used in both Java and JavaScript on a very easy manner. In Java, you can use Google Gson to convert fullworthy Java objects to JSON and vice versa.

List<Product> products = productDAO.list(); // Product is just a Javabean with properties `id`, `name` and `description`.
String json = new Gson().toJson(products);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);

In JavaScript you can use jQuery's $.getJSON() to get it "instantly". Let's display it in a <table>.

$.getJSON('myservlet', function(data) {
    var table = $('<table>').appendTo($('#data'));
    $.each(data, function(i, product) {
        var row = $('<tr>').appendTo(table);
        $('<td>').text(product.id).appendTo(row);
        $('<td>').text(product.name).appendTo(row);
        $('<td>').text(product.description).appendTo(row);
    });
});

See also:

BalusC