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

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

本节书摘来自异步社区《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("'", "&#39;")
                    + "'/></td></tr>");
            writer.println("<tr><td>City:</td><td>"
                    + "<input name='city' value='" +
                    customer.getCity().replaceAll("'", "&#39;")
                    + "'/></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所示。

screenshot

图2.4 客户列表

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

screenshot

图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方法。

相关文章
|
23天前
|
Java
学校教师管理系统【JSP+Servlet+JavaBean】(Java课设)
学校教师管理系统【JSP+Servlet+JavaBean】(Java课设)
19 1
|
12天前
|
数据采集 前端开发 Java
数据塑造:Spring MVC中@ModelAttribute的高级数据预处理技巧
数据塑造:Spring MVC中@ModelAttribute的高级数据预处理技巧
23 3
|
12天前
|
存储 前端开发 Java
会话锦囊:揭示Spring MVC如何巧妙使用@SessionAttributes
会话锦囊:揭示Spring MVC如何巧妙使用@SessionAttributes
14 1
|
12天前
|
前端开发 Java Spring
数据之桥:深入Spring MVC中传递数据给视图的实用指南
数据之桥:深入Spring MVC中传递数据给视图的实用指南
29 3
|
21天前
|
前端开发 安全 Java
使用Java Web框架:Spring MVC的全面指南
【4月更文挑战第3天】Spring MVC是Spring框架的一部分,用于构建高效、模块化的Web应用。它基于MVC模式,支持多种视图技术。核心概念包括DispatcherServlet(前端控制器)、HandlerMapping(请求映射)、Controller(处理请求)、ViewResolver(视图解析)和ModelAndView(模型和视图容器)。开发流程涉及配置DispatcherServlet、定义Controller、创建View、处理数据、绑定模型和异常处理。
使用Java Web框架:Spring MVC的全面指南
|
23天前
|
Java
排课系统【JSP+Servlet+JavaBean】(Java课设)
排课系统【JSP+Servlet+JavaBean】(Java课设)
7 0
|
23天前
|
Java
仓库管理系统【JSP+Servlet+JavaBean】(Java课设)
仓库管理系统【JSP+Servlet+JavaBean】(Java课设)
13 0
|
23天前
|
Java
学校人员管理系统【JSP+Servlet+JavaBean】(Java课设)
学校人员管理系统【JSP+Servlet+JavaBean】(Java课设)
16 0
|
23天前
|
Java
人事管理系统【JSP+Servlet+JavaBean】(Java课设)
人事管理系统【JSP+Servlet+JavaBean】(Java课设)
18 0
|
1月前
使用Servlet上传多张图片——前台页面层(Index.jsp)
使用Servlet上传多张图片——前台页面层(Index.jsp)
14 0