为什么我的Ajax调用刷新页面? (即再次调用servlet)

发布于 2024-10-08 01:48:27 字数 7174 浏览 0 评论 0原文

我正在研究使用 Java 的 RESTful Web 服务。 我的环境使用 Netbean 和 GlassFish v3。

我有一个页面 URL /inventoryList ,该 URL 映射到 web.xml 中的 InventoryApp.java servlet

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
    <servlet>
        <servlet-name>inventory servlet</servlet-name>
        <servlet-class>local.test.servlet.InventoryApp</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>inventory servlet</servlet-name>
        <url-pattern>/inventoryList</url-pattern>
    </servlet-mapping>
</web-app>

在 servlet 中,它获取来自数据库的库存项目信息列表并显示到 JSP 页面。

inventory.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>

        <script type="text/javascript">

        function ajaxGet(inventoryId) {
            alert(inventoryId);
            var xmlHttp = new XMLHttpRequest();
            xmlHttp.onreadystatechange = function() {

                alert('sigh');

                if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    alert('ready 4');
                    alert('After ready4 ===> ' + xmlHttp.responseText);

                    displayInventoryHtml(xmlHttp);

                }
            }
            var url = "resources/inventory/" + inventoryId;
            xmlHttp.open("GET", url, true);
            xmlHttp.send(null);
        }

        function displayInventoryHtml(responseAjax) {
            document.getElementById('inventoryItem').innerHTML = responseAjax.responseText;
        }

        </script>

    </head>
    <body>
        <h1>Inventory page</h1>

        <table border="1" cellspacing="1" cellpadding="5">
            <th>id</th>
            <th>amount</th>
            <c:forEach items="${inventoryList}" var="inv" >
                <tr>
                    <td>${inv.id}</td>
                    <td><a href="" onclick="ajaxGet(${inv.id})">${inv.amount}</a></td>
                </tr>
            </c:forEach>
        </table>
        <hr />
        <div id="inventoryItem">
        </div>


    </body>
</html>

如您所见,inventory.jsp 将成功输出库存项目列表。

到目前为止,一切都很好。

在这里,我将库存金额值的输出作为 Ajax 调用的链接。

<td><a href="" onclick="ajaxGet(${inv.id})">${inv.amount}</a></td>

它调用 HTTP GET 方法REST 服务(代码所示)下面)将获取指定 id(数据库主 id)的库存数据,并且我将 Ajax responseText 放入 div (id=inventoryItem)

InventoryResource.java

package local.test.jaxrs;

import java.util.List;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import local.test.dao.InventoryDao;
import local.test.session.Inventory;

@Path("/inventory")
public class InventoryResource {
    @Context
    private UriInfo context;

    /** Creates a new instance of InventoryResource */
    public InventoryResource() {
    }


    @Path("{inv_id}")
    @GET
    @Produces("text/html")
    public String getJson(@PathParam("inv_id") String inventory_id) {
        System.out.println("GET is being handled");

        Inventory invBean = new Inventory(Integer.valueOf(inventory_id));
        InventoryDao invDao = new InventoryDao();
        List<Inventory> inv = invDao.findById(invBean);

        String html = "<b>" + inv.get(0).getId() + "</b><br /><b>" + inv.get(0).getAmount() + "</b><br />";

        return html;

    }
}//end class

当我测试此代码时,一切正常。 Ajax 成功获取数据并插入到 HTML DIV 标记中,库存数据显示半秒后消失。

使用 firebug 并查看 glassfish v3 服务器日志,我认为最后,它再次调用 InventoryApp.java servlet,这导致页面重定向到 /inventoryList

我知道 Ajax 是部分请求,不应导致页面刷新。

我已经在这几天了,有人能给我提示发生了什么事吗? 我不确定像我一样将 servlet 和 web.xml 与 REST 混合起来是否可行。

仅供参考,我的 InventoryApp.java servlet 代码

package local.test.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import local.test.dao.InventoryDao;
import local.test.session.Inventory;


@WebServlet(name="InventoryApp", urlPatterns={"/InventoryApp"})
public class InventoryApp extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {

        } finally { 
            out.close();
        }
    } 

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        InventoryDao invDao = new InventoryDao();
        List<Inventory> invList =  invDao.findAll();

        //this list looks ok...
        System.out.println("================= do get servelt ===" + invList.get(0));

        request.setAttribute("inventoryList", invList);
        request.getRequestDispatcher("inventory.jsp").forward(request, response);

        //processRequest(request, response); //commented not sure what it is..
    } 
}//end class

I'm studying RESTful web service using Java.
My environment is using Netbean with GlassFish v3.

I have a page URL /inventoryList which is URL mapped to InventoryApp.java servlet in web.xml

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
    <servlet>
        <servlet-name>inventory servlet</servlet-name>
        <servlet-class>local.test.servlet.InventoryApp</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>inventory servlet</servlet-name>
        <url-pattern>/inventoryList</url-pattern>
    </servlet-mapping>
</web-app>

In the servlet, it obtains list of inventory item info from DB and display to the JSP page.

inventory.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>

        <script type="text/javascript">

        function ajaxGet(inventoryId) {
            alert(inventoryId);
            var xmlHttp = new XMLHttpRequest();
            xmlHttp.onreadystatechange = function() {

                alert('sigh');

                if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    alert('ready 4');
                    alert('After ready4 ===> ' + xmlHttp.responseText);

                    displayInventoryHtml(xmlHttp);

                }
            }
            var url = "resources/inventory/" + inventoryId;
            xmlHttp.open("GET", url, true);
            xmlHttp.send(null);
        }

        function displayInventoryHtml(responseAjax) {
            document.getElementById('inventoryItem').innerHTML = responseAjax.responseText;
        }

        </script>

    </head>
    <body>
        <h1>Inventory page</h1>

        <table border="1" cellspacing="1" cellpadding="5">
            <th>id</th>
            <th>amount</th>
            <c:forEach items="${inventoryList}" var="inv" >
                <tr>
                    <td>${inv.id}</td>
                    <td><a href="" onclick="ajaxGet(${inv.id})">${inv.amount}</a></td>
                </tr>
            </c:forEach>
        </table>
        <hr />
        <div id="inventoryItem">
        </div>


    </body>
</html>

As you can see the inventory.jsp would successfully output the list of inventory item.

So far so good.

Here, I made the output of inventory amount value to be a link to Ajax call.

<td><a href="" onclick="ajaxGet(${inv.id})">${inv.amount}</a></td>

It calls HTTP GET method and REST service (code shown below) will get inventory data of specified id (database primary id) and I put the Ajax responseText into the div (id=inventoryItem)

InventoryResource.java

package local.test.jaxrs;

import java.util.List;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import local.test.dao.InventoryDao;
import local.test.session.Inventory;

@Path("/inventory")
public class InventoryResource {
    @Context
    private UriInfo context;

    /** Creates a new instance of InventoryResource */
    public InventoryResource() {
    }


    @Path("{inv_id}")
    @GET
    @Produces("text/html")
    public String getJson(@PathParam("inv_id") String inventory_id) {
        System.out.println("GET is being handled");

        Inventory invBean = new Inventory(Integer.valueOf(inventory_id));
        InventoryDao invDao = new InventoryDao();
        List<Inventory> inv = invDao.findById(invBean);

        String html = "<b>" + inv.get(0).getId() + "</b><br /><b>" + inv.get(0).getAmount() + "</b><br />";

        return html;

    }
}//end class

When I test this code, everything works just fine. The Ajax successfully get data and insert into the HTML DIV tag and the inventory data shows up for half second and disappear.

Using firebug and looking at glassfish v3 server log, I figure that at the end, it is calling InventoryApp.java servlet AGAIN which cause the page to redirect to /inventoryList

I know Ajax is partial request and should not cause page to refresh.

I'm stack in this for few days now, could anyone give me hint what's going on?
I'm not sure if it is practical to mix servlet and web.xml with REST like I do.

FYI, my InventoryApp.java servlet code

package local.test.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import local.test.dao.InventoryDao;
import local.test.session.Inventory;


@WebServlet(name="InventoryApp", urlPatterns={"/InventoryApp"})
public class InventoryApp extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {

        } finally { 
            out.close();
        }
    } 

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        InventoryDao invDao = new InventoryDao();
        List<Inventory> invList =  invDao.findAll();

        //this list looks ok...
        System.out.println("================= do get servelt ===" + invList.get(0));

        request.setAttribute("inventoryList", invList);
        request.getRequestDispatcher("inventory.jsp").forward(request, response);

        //processRequest(request, response); //commented not sure what it is..
    } 
}//end class

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苄①跕圉湢 2024-10-15 01:48:27
<a href="" onclick="ajaxGet(${inv.id})">${inv.amount}</a>

去掉href属性

<a onclick="ajaxGet(${inv.id})">${inv.amount}</a>

或者取消click事件的推广

<a href="" onclick="ajaxGet(${inv.id}); return false;">${inv.amount}</a>
<a href="" onclick="ajaxGet(${inv.id})">${inv.amount}</a>

remove the href attribute

<a onclick="ajaxGet(${inv.id})">${inv.amount}</a>

or cancel the promotion of the click event

<a href="" onclick="ajaxGet(${inv.id}); return false;">${inv.amount}</a>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文