《Servlet、JSP和Spring MVC初学指南》——2.2 隐藏域

    xiaoxiao2024-01-23  25

    本节书摘来自异步社区《Servlet、JSP和Spring MVC初学指南》一书中的第2章,第2.2节,作者:【加】Budi Kurniawan(克尼亚万) , 【美】Paul Deck著,更多章节内容可以访问云栖社区“异步社区”公众号查看

    2.2 隐藏域

    使用隐藏域来保持状态类似于URL重写技术,但不是将值附加到URL上,而是放到HTML表单的隐藏域中。当表单提交时,隐藏域的值也同时提交到服务器端。隐藏域技术仅当网页有表单时有效。该技术相对于URL重写的优势在于:没有字符数限制,同时无须额外的编码。但该技术同URL重写一样,不适合跨越多个界面。

    清单2.3展示了如何通过隐藏域来更新客户信息。清单2.2的Customer类为客户对象模型。

    清单2.2 Customer类

    package app02a.hiddenfields; public class Customer { private int id; private String name; private String city; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }

    清单2.3 CustomerServlet类

    package app02a.hiddenfields; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /* * Not thread-safe. For illustration purpose only */ @WebServlet(name = "CustomerServlet", urlPatterns = { "/customer", "/editCustomer", "/updateCustomer"}) public class CustomerServlet extends HttpServlet { private static final long serialVersionUID = -20L; private List<Customer> customers = new ArrayList<Customer>(); @Override public void init() throws ServletException { Customer customer1 = new Customer(); customer1.setId(1); customer1.setName("Donald D."); customer1.setCity("Miami"); customers.add(customer1); Customer customer2 = new Customer(); customer2.setId(2); customer2.setName("Mickey M."); customer2.setCity("Orlando"); customers.add(customer2); } private void sendCustomerList(HttpServletResponse response) throws IOException { response.setContentType("text/html"); PrintWriter writer = response.getWriter(); writer.println("<html><head><title>Customers</title></head>" + "<body><h2>Customers </h2>"); writer.println("<ul>"); for (Customer customer : customers) { writer.println("<li>" + customer.getName() + "(" + customer.getCity() + ") (" + "<a href='editCustomer?id=" + customer.getId() + "'>edit</a>)"); } writer.println("</ul>"); writer.println("</body></html>"); } private Customer getCustomer(int customerId) { for (Customer customer : customers) { if (customer.getId() == customerId) { return customer; } } return null; } private void sendEditCustomerForm(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html"); PrintWriter writer = response.getWriter(); int customerId = 0; try { customerId = Integer.parseInt(request.getParameter("id")); } catch (NumberFormatException e) { } Customer customer = getCustomer(customerId); if (customer != null) { writer.println("<html><head>" + "<title>Edit Customer</title></head>" + "<body><h2>Edit Customer</h2>" + "<form method='post' " + "action='updateCustomer'>"); writer.println("<input type='hidden' name='id' value='" + customerId + "'/>"); writer.println("<table>"); writer.println("<tr><td>Name:</td><td>" + "<input name='name' value='" + customer.getName().replaceAll("'", "'") + "'/></td></tr>"); writer.println("<tr><td>City:</td><td>" + "<input name='city' value='" + customer.getCity().replaceAll("'", "'") + "'/></td></tr>"); writer.println("<tr>" + "<td colspan='2' style='text-align:right'>" + "<input type='submit' value='Update'/></td>" + "</tr>"); writer.println("<tr><td colspan='2'>" + "<a href='customer'>Customer List</a>" + "</td></tr>"); writer.println("</table>"); writer.println("</form></body>"); } else { writer.println("No customer found"); } } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uri = request.getRequestURI(); if (uri.endsWith("/customer")) { sendCustomerList(response); } else if (uri.endsWith("/editCustomer")) { sendEditCustomerForm(request, response); } } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // update customer int customerId = 0; try { customerId = Integer.parseInt(request.getParameter("id")); } catch (NumberFormatException e) { } Customer customer = getCustomer(customerId); if (customer != null) { customer.setName(request.getParameter("name")); customer.setCity(request.getParameter("city")); } sendCustomerList(response); } }

    CustomerServlet类继承自HttpServlet,其URL映射分别为/customer、/editCustomer和 /updateCustomer。前两个URL会调用Servlet的doGet方法,而/updateCustomer 会调用doPost方法。

    /customer是本例的入口URL。该URL会列举出在init 方法中所初始化的类级别的列表对象customers(在真实应用中,通常是从数据库中获取用户信息),如图2.4所示。

    图2.4 客户列表

    如图2.4所示,每个客户信息后都有一个edit链接,每个edit链接的href属性为 /editCustomer? id=customerId。当通过/editCustomer访问servlet时,servlet会返回一个编辑表单,如图2.5所示。

    图2.5 客户编辑表单

    如果你点击的是第一个客户,servlet返回表单中的隐藏域如下:

    <form method='post' action='updateCustomer'> <input type='hidden' name='id' value='1'/> <table> <tr><td>Name:</td> <td><input name='name' value='Donald DC.'/></td> </tr> <tr> <td>City:</td><td><input name='city' value='Miami'/></td> </tr> <tr> <td colspan='2' style='text-align:right'> <input type='submit' value='Update'/> </td> </tr> <tr> <td colspan='2'><a href='customer'>Customer List</a></td> </tr> </table> </form>

    该隐藏域为所编辑的客户id,因此当表单提交时,服务端就知道应更新哪个客户信息。

    需要强调的是,表单是通过post方式提交的,因此调用的是servlet的doPost方法。

    相关资源:敏捷开发V1.0.pptx
    最新回复(0)