Как передать текущий элемент методу Java, нажав гиперссылку или кнопку на странице JSP? - PullRequest
4 голосов
/ 20 июня 2010

У меня есть таблица HTML со строками, извлеченными из базы данных, отображаемой в этой таблице. Я хочу, чтобы пользователь мог удалить строку, нажав на гиперссылку или кнопку удаления рядом с каждой строкой.

Как вызвать функцию JSP на странице, когда пользователь нажимает на каждую из этих гиперссылок или кнопку удаления, чтобы я мог удалить запись этой строки из базы данных? Что именно должен тег <a> или <button> вызывать функцию JSP?

Обратите внимание, что мне нужно вызывать функцию JSP, а не функцию JavaScript.

1 Ответ

8 голосов
/ 20 июня 2010

Самый простой способ: просто дайте ссылке указать на страницу 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 для стилизации кнопки, чтобы она выглядела как ссылка.Редактировать ссылки, которые просто предварительно загружают элемент, чтобы заполнить форму редактирования, можно безопасно: GET.

  2. Помещение бизнес-логики ( функции , как вы ее называете) в JSP с использованием скриптлетов (эти <% %> вещи) не рекомендуется.Вы должны использовать Servlet для управления 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 для установки) для отображения products в таблице со ссылкой для редактирования и кнопкой удаления в каждой строке:

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

ПримечаниеРазница в подходе: ссылка редактирования запускает запрос GET с уникальным идентификатором элемента в качестве параметра запроса.Однако кнопка удаления запускает запрос POST, в результате чего уникальный идентификатор элемента передается как значение самой кнопки.

Сохраните его как 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.

См. Также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...