如何通过单击jsp页面中的超链接或按钮将当前项传递给java方法?

scyqe7ek  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(408)

我有一个html表,其中包含从该表中显示的数据库中获取的行。我希望用户能够通过单击每行旁边的删除超链接或按钮来删除一行。
当用户单击每个delete超链接或按钮时,如何调用页面上的jsp函数,以便从数据库中删除该行的条目?到底该怎么办 <a> 或者 <button> 标签必须调用jsp函数吗?
注意,我需要调用一个jsp函数,而不是javascript函数。

bis0qfac

bis0qfac1#

最简单的方法:只需让链接指向一个jsp页面,并将行id作为参数传递:

<a href="delete.jsp?id=1">delete</a>

而且在 delete.jsp (我把明显的请求参数检查/验证放在一边):

<% dao.delete(Long.valueOf(request.getParameter("id"))); %>

然而,这是一个相当糟糕的做法(这仍然是一个轻描淡写的说法),原因有两个:
修改服务器端数据的http请求不应该通过get完成,而应该通过post完成。链接是隐式的。想象一下,当像googlebot这样的网络爬虫试图跟踪所有删除链接时会发生什么。你应该使用 <form method="post"> 和一个 <button type="submit"> 用于删除操作。但是,您可以使用css来设置按钮的样式,使其看起来像一个链接。只需预加载项目以预填充编辑表单的编辑链接可以安全地获得。
使用scriptlets(那些 <% %> 事情)是不鼓励的。您应该使用servlet来控制、预处理和后处理http请求。
由于您在问题中没有提到任何关于servlet的信息,我怀疑您已经在使用scriptlets从db加载数据并将其显示在表中。这也应该由servlet来完成。
下面是一个基本的开球例子如何做到这一切。我不知道表数据代表什么,所以让我们来看看 Product 举个例子。

public class Product {
    private Long id;
    private String name;
    private String description;
    private BigDecimal price;
    // Add/generate public getters and setters.
}

然后是使用jstl的jsp文件(只需将jstl-1.2.jar放到 /WEB-INF/lib 要在表格中显示产品(每行有一个编辑链接和一个删除按钮),请执行以下操作:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
...
<form action="products" method="post">
    <table>
        <c:forEach items="${products}" var="product">
            <tr>
                <td><c:out value="${fn:escapeXml(product.name)}" /></td>
                <td><c:out value="${product.description}" /></td>
                <td><fmt:formatNumber value="${product.price}" type="currency" currencyCode="USD" /></td>
                <td><a href="${pageContext.request.contextPath}/product?edit=${product.id}">edit</a></td>
                <td><button type="submit" name="delete" value="${product.id}">delete</button></td>
            </tr>
        </c:forEach>
    </table>
    <a href="${pageContext.request.contextPath}/product">add</a>
</form>

注意方法的不同:edit链接触发一个get请求,请求参数为项的唯一标识符。但是,delete按钮触发post请求,从而将项的唯一标识符作为按钮本身的值传递。
另存为 products.jsp 把它放进去 /WEB-INF 文件夹,这样就不能通过url直接访问它(这样最终用户就被迫为此调用servlet)。
下面是servlet的大致外观(为了简洁起见,省略了验证):

@WebServlet("/products")
public class ProductsServlet extends HttpServlet {

    private ProductDAO productDAO; // EJB, plain DAO, etc.

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Product> products = productDAO.list();
        request.setAttribute("products", products); // Will be available as ${products} in JSP.
        request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String delete = request.getParameter("delete");

        if (delete != null) { // Is the delete button pressed?
            productDAO.delete(Long.valueOf(delete));
        }

        response.sendRedirect(request.getContextPath() + "/products"); // Refresh page with table.
    }

}

下面是如何在 /WEB-INF/product.jsp 可能看起来像:

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<form action="product" method="post">
    <label for="name">Name</label>
    <input id="name" name="name" value="${fn:escapeXml(product.name)}" />
    <br/>
    <label for="description">Description</label>
    <input id="description" name="description" value="${fn:escapeXml(product.description)}" />
    <br/>
    <label for="price">Price</label>
    <input id="price" name="price" value="${fn:escapeXml(product.price)}" />
    <br/>
    <button type="submit" name="save" value="${product.id}">save</button>
</form>

这个 fn:escapeXml() 只是为了在重新显示编辑数据时防止xss攻击,它的作用与 <c:out> ,仅更适合在属性中使用。
下面是 product servlet看起来像(同样,为了简洁起见,省略了转换/验证):

@WebServlet("/product")
public class ProductServlet extends HttpServlet {

    private ProductDAO productDAO; // EJB, plain DAO, etc.

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String edit = request.getParameter("edit");

        if (edit != null) { // Is the edit link clicked?
            Product product = productDAO.find(Long.valueOf(delete));
            request.setAttribute("product", product); // Will be available as ${product} in JSP.
        }

        request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String save = request.getParameter("save");

        if (save != null) { // Is the save button pressed? (note: if empty then no product ID was supplied, which means that it's "add product".
            Product product = (save.isEmpty()) ? new Product() : productDAO.find(Long.valueOf(save));
            product.setName(request.getParameter("name"));
            product.setDescription(request.getParameter("description"));
            product.setPrice(new BigDecimal(request.getParameter("price")));
            productDAO.save(product);
        }

        response.sendRedirect(request.getContextPath() + "/products"); // Go to page with table.
    }

}

部署并运行它。你可以打开tablehttp://example.com/contextname/products.
另请参见:
我们的servlets wiki页面(还包含一个验证示例)
servlet中的doget和dopost
使用mvc和dao模式在jsp页面中以html显示jdbc结果集

相关问题