Как передать текущий элемент методу 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"))); %>

Это, однако, довольно плохая практика (это было все еще преуменьшение) и по двум причинам:

  1. HTTP-запросы, которые изменяют данные на стороне сервера, должны выполняться не GET, а POST. Ссылки неявные GET. Представьте, что произойдет, если веб-сканер, такой как googlebot, попытается перейти по всем ссылкам на удаление. Вы должны использовать <form method="post"> и <button type="submit"> для действия удаления. Однако вы можете использовать CSS для стилизации кнопки, чтобы она выглядела как ссылка. Редактировать ссылки, которые просто предварительно загружают элемент, чтобы заполнить форму редактирования, можно смело.

  2. Помещение бизнес-логики (функции, как вы ее называете) в 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.

Смотрите также:

Другие вопросы по тегам