我有一個HTML表格,從該表格中顯示的數據庫中提取行。我希望用戶能夠通過單擊除每行之外的刪除超鏈接或按鈕來刪除一行。如何通過單擊JSP頁面中的超鏈接或按鈕將當前項傳遞給Java方法?
如何在頁面上調用JSP函數,當用戶單擊每個刪除超鏈接或按鈕時,以便我可以從數據庫中刪除該行的條目? <a>
或<button>
標籤究竟應該調用JSP函數?
請注意,我需要調用一個JSP函數,而不是JavaScript函數。
我有一個HTML表格,從該表格中顯示的數據庫中提取行。我希望用戶能夠通過單擊除每行之外的刪除超鏈接或按鈕來刪除一行。如何通過單擊JSP頁面中的超鏈接或按鈕將當前項傳遞給Java方法?
如何在頁面上調用JSP函數,當用戶單擊每個刪除超鏈接或按鈕時,以便我可以從數據庫中刪除該行的條目? <a>
或<button>
標籤究竟應該調用JSP函數?
請注意,我需要調用一個JSP函數,而不是JavaScript函數。
最簡單的方法:只讓該鏈接指向一個JSP頁面,並通過行ID作爲參數:
<a href="delete.jsp?id=1">delete</a>
而且在delete.jsp
(我留下明顯的請求參數檢驗/驗證除外):
<% dao.delete(Long.valueOf(request.getParameter("id"))); %>
但是,這是一個非常poor practice(即仍然是一個保守的),並有兩個原因:
修改服務器端數據的HTTP請求不應該由GET完成,而是由POST完成。鏈接是隱式的GET。想象一下,當像googlebot這樣的網絡爬蟲試圖關注所有刪除鏈接時會發生什麼。您應該使用<form method="post">
和<button type="submit">
作爲刪除操作。但是,您可以使用CSS將按鈕設置爲鏈接樣式。編輯鏈接,只需預先加載項目以預先填寫編輯表單即可安全地進行GET。
把業務邏輯使用小腳本(那些<% %>
東西)氣餒(功能你稱呼它)在JSP。您應該使用一個Servlet來控制,預處理和後處理HTTP請求。
既然你沒有告訴你的問題一個servlet的任何一句話,我懷疑你已經在使用小腳本從數據庫加載數據,並在表中顯示。這也應該由一個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進行安裝)來顯示產品表中的每一行中的編輯鏈接和刪除按鈕:
<%@ 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的大致模樣(驗證略去了):
@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 attacks,它的確與<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.
}
}
部署並運行它。您可以通過http://example.com/contextname/products打開表格。
參見:
謝謝。我會嘗試實現這一點,因爲它更有意義。我現在的代碼很混亂,需要重組來實現你提出的方法。並感謝參考鏈接。 – nilay 2010-06-20 17:40:53
不客氣。是的,將所有內容混淆在一個大的JSP文件中是相當混亂和難以維護:)祝你好運。 – BalusC 2010-06-20 17:54:29