views:

140

answers:

1

Hi I try to run a java server on Jetty which should respond to an ajax call. Unfortunately the response seems to be empty when I call it with ajax. When I call http://localhost:8081/?id=something I get an answer.

The Java Server:

   public class Answer extends AbstractHandler
{
    public void handle(String target,
                       Request baseRequest,
                       HttpServletRequest request,
                       HttpServletResponse response) 
        throws IOException, ServletException
    {
        String id = request.getParameter("id");
        response.setContentType("text/xml");
        response.setHeader("Cache-Control", "no-cache");

        response.setContentLength(19+id.length());
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().write("<message>"+id+"</message>");
        //response.setContentType("text/html;charset=utf-8");

        response.flushBuffer();
        baseRequest.setHandled(true);
    }

    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8081);
        server.setHandler(new Answer());

        server.start();
        server.join();
    }
}

The js and html:

<html>
<head>
<script>
var req;

function validate() {
   var idField = document.getElementById("userid");
   var url = "validate?id=" + encodeURIComponent(idField.value);
   if (typeof XMLHttpRequest != "undefined") {
       req = new XMLHttpRequest();
   } else if (window.ActiveXObject) {
       req = new ActiveXObject("Microsoft.XMLHTTP");
   }
   req.open("GET", "http://localhost:8081?id=fd", true);
   req.onreadystatechange = callback;
   req.send(null);
}


function callback() {
    if (req.readyState == 4) {
        if (req.status == 200) {
             var message = req.responseXML.getElementsByTagName("message")[0];
             document.getElementById("userid").innerHTML = "message.childNodes[0].nodeValue";
        }
    }
}

</script>
</head>
<body onload="validate('foobar')">
<div id="userid">hannak</div>
</body>
</html>

I'm actually don't know what I'm doing wrong here. Maybe someone has a good idea.

greetings chris

A: 

You're probably reading your HTML file from disk, i.e. with a "file:///" URL. Web browsers only allow XmlHttpRequests to the host where the page came from, that's why your request doesn't work.

I took the embedded Jetty tutorial and modified your code:

Answer.java:

package test;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;

public class Answer extends AbstractHandler {
  public void handle(String target, Request baseRequest, HttpServletRequest request,
      HttpServletResponse response) throws IOException, ServletException {
    String id = request.getParameter("id");
    response.setContentType("text/xml");
    response.setHeader("Cache-Control", "no-cache");
    response.setContentLength(19 + id.length());
    response.setStatus(HttpServletResponse.SC_OK);
    response.getWriter().write("<message>" + id + "</message>");
    response.flushBuffer();
    baseRequest.setHandled(true);
  }

  public static void main(String[] args) throws Exception {
    Server server = new Server(8081);

    ResourceHandler resource_handler = new ResourceHandler();
    resource_handler.setDirectoriesListed(true);
    resource_handler.setWelcomeFiles(new String[] { "index.html" });
    resource_handler.setResourceBase(".");

    HandlerList handlers = new HandlerList();
    handlers.setHandlers(new Handler[] { resource_handler, new Answer() });

    server.setHandler(handlers);
    server.start();
    server.join();
  }
}

And index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>AJAX Test</title>
    <script type="text/javascript">
      var req;

      function validate() {
        if (typeof XMLHttpRequest != "undefined") {
          req = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
          req = new ActiveXObject("Microsoft.XMLHTTP");
        }
        req.open("GET", "http://localhost:8081/SomeResourceThatDoesntExistSoOurTestHandlerGetsCalled?id=fd", true);
        req.onreadystatechange = callback;
        req.send(null);
      }

      function callback() {
        if (req.readyState == 4 && req.status == 200) {
          var message = req.responseXML.getElementsByTagName("message")[0];
          document.getElementById("userid").innerHTML = message.childNodes[0].nodeValue;
        }
      }
    </script>
  </head>
  <body onload="validate()">
    <div id="userid">hannak</div>
  </body>
</html>

These are my changes to your code:

  • I removed unneccessary stuff (probably from your experiments ☺)
  • I added a ResourceHandler to the Jetty server which delivers the index.html file when no path is given on the URL
  • I changed the request URL in the Javascript part so the request goes to the Answer handler
  • I un-quoted the message handling in the callback function, so the contents of the answer message get displayed (always fd due to the hardcoded GET-URL-parameter)

Put the index.html in your base working directory and run the Answer class again -- when you point your browser to http://localhost:8081/ things should work as you wanted them to. First Jetty delivers the index.html to the browser, the browser then makes the XHR GET request and on success replaces "hannak" with "fd".

HTH!

Henning