Как передать текущий элемент методу Java, нажав гиперссылку или кнопку на странице JSP?
У меня есть HTML-таблица со строками, извлеченными из базы данных, отображаемой в этой таблице. Я хочу, чтобы пользователь мог удалить строку, нажав на гиперссылку или кнопку удаления рядом с каждой строкой.
Как вызвать функцию JSP на странице, когда пользователь нажимает на каждую из этих гиперссылок или кнопку удаления, чтобы я мог удалить запись этой строки из базы данных? Что именно должно <a>
или же <button>
тег должен вызывать функцию JSP?
Обратите внимание, что мне нужно вызывать функцию JSP, а не функцию JavaScript.
1 ответ
Самый простой способ: просто дайте ссылке указать на страницу JSP и передать идентификатор строки в качестве параметра:
<a href="delete.jsp?id=1">delete</a>
И в delete.jsp
(Я оставляю очевидные параметры проверки / проверки в стороне):
<% dao.delete(Long.valueOf(request.getParameter("id"))); %>
Это, однако, довольно плохая практика (это было все еще преуменьшение) и по двум причинам:
HTTP-запросы, которые изменяют данные на стороне сервера, должны выполняться не GET, а POST. Ссылки неявные GET. Представьте, что произойдет, если веб-сканер, такой как googlebot, попытается перейти по всем ссылкам на удаление. Вы должны использовать
<form method="post">
и<button type="submit">
для действия удаления. Однако вы можете использовать CSS для стилизации кнопки, чтобы она выглядела как ссылка. Редактировать ссылки, которые просто предварительно загружают элемент, чтобы заполнить форму редактирования, можно смело.Помещение бизнес-логики (функции, как вы ее называете) в JSP с использованием скриптлетов
<% %>
вещи) не рекомендуется. Вы должны использовать сервлет для контроля, предварительной обработки и пост-обработки HTTP-запросов.
Поскольку вы не сказали ни слова о сервлете в своем вопросе, я подозреваю, что вы уже используете скриптлеты для загрузки данных из БД и отображения их в таблице. Это также должно быть сделано с помощью сервлета.
Вот основной пример, как это сделать. Я понятия не имею, что представляют собой данные таблицы, поэтому давайте возьмем Product
В качестве примера.
public class Product {
private Long id;
private String name;
private String description;
private BigDecimal price;
// Add/generate public getters and setters.
}
И затем файл JSP, который использует JSTL (просто бросьте 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>
Назови это products.jsp
и положить его в /WEB-INF
папка, так что она не доступна напрямую по URL (так что конечный пользователь вынужден вызывать сервлет для этого).
Вот как примерно выглядит сервлет (проверка для краткости опущена):
@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
сервлет может выглядеть следующим образом (опять же, для краткости преобразование / проверка опущены):
@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.
Смотрите также:
- Вики-страница нашего сервлета (также содержит пример с валидацией)
- doGet и doPost в сервлетах
- Показать JDBC ResultSet в HTML на странице JSP с использованием шаблона MVC и DAO