如何通过单击JSP页面中的超链接或button将当前项传递给Java方法?

我有一个HTML表格,从该表格中显示的数据库中提取行。 我希望用户能够通过单击除了每行之外的删除超链接或button来删除一行。

如何在页面上调用JSP函数,当用户单击每个删除超链接或button时,以便我可以从数据库中删除该行的条目? 究竟应该<a><button>标记调用JSP函数?

请注意,我需要调用一个JSP函数,而不是JavaScript函数。

最简单的方法:让链接指向一个JSP页面并传递行ID作为参数:

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

而在delete.jsp (我离开明显的请求参数检查/validation旁边)

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

然而,这是一个相当差的做法 (这仍然是轻描淡写),由于两个原因:

  1. 修改服务器端数据的HTTP请求不应该由GET完成,而应该由POST完成 。 链接是隐式的GET。 想象一下当像googlebot这样的networking爬虫试图关注所有的删除链接时会发生什么。 您应该使用<form method="post"><button type="submit">来执行删除操作。 但是,您可以使用CSS将button设置为链接。 编辑链接,只是预加载项目,以预先填写编辑表单可以安全地得到GET。

  2. 不鼓励使用scriptlets (这些<% %>东西)在业务逻辑( function ,你叫它)在JSP中。 您应该使用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文件(只需在/WEB-INF/lib 下载jstl-1.2.jar来安装它)将产品显示在每行中具有编辑链接和删除button的表格中:

 <%@ 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> 

将其命名为products.jsp ,并将其放在/WEB-INF文件夹中,以使其不能通过URL直接访问(以便最终用户被迫为此调用servlet)。

下面是servlet粗略的样子(为简洁起见,省略了validation):

 @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>完全一样,只是更适合用在attribtues中。

以下是product servlet的外观(同样为简洁起见,省略了转换/validation):

 @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. } } 

部署并运行它。 您可以通过http://example.com/contextname/products打开表格。;

也可以看看:

  • 我们的servlets wiki页面 (也包含一个validation示例)
  • doGet和doPost在Servlets中
  • 在JSP页面中使用MVC和DAO模式在HTML中显示JDBC ResultSet