Ответ сервлета Jetty на Ajax всегда пуст - PullRequest
1 голос
/ 12 мая 2010

Привет, я пытаюсь запустить java-сервер на Jetty, который должен ответить на вызов ajax. К сожалению, ответ кажется пустым, когда я звоню с ajax. Когда я звоню http://localhost:8081/?id=something, я получаю ответ.

Сервер Java:

   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();
    }
}

JS и 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>

Я на самом деле не знаю, что я здесь делаю неправильно. Может быть, у кого-то есть хорошая идея.

привет Крис

1 Ответ

4 голосов
/ 13 мая 2010

Вы, вероятно, читаете ваш HTML-файл с диска, то есть с URL-адресом «file: ///». Веб-браузеры разрешают запросы XmlHttpRequest только на хост, с которого пришла страница, поэтому ваш запрос не работает.

Я взял встроенный учебник Jetty и изменил ваш код:

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();
  }
}

И 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>

Это мои изменения в вашем коде:

  • Я удалил ненужные вещи (вероятно, из ваших экспериментов ☺)
  • Я добавил ResourceHandler на сервер Jetty, который доставляет файл index.html, когда в URL не указан путь
  • Я изменил URL запроса в части Javascript, поэтому запрос переходит к обработчику Answer
  • Я отключил обработку сообщений в функции callback, поэтому отображается содержимое ответного сообщения (всегда fd из-за жестко заданного параметра GET-URL)

Поместите index.html в базовый рабочий каталог и снова запустите класс Answer - когда вы указываете браузеру на http://localhost:8081/, все должно работать так, как вы хотели. Сначала Jetty доставляет index.html в браузер, затем браузер делает запрос XHR GET и в случае успеха заменяет «hannak» на «fd».

НТН!

...