2.2 隐藏域
使用隐藏域来保持状态类似于URL
重写技术,但不是将值附加到URL
上,而是放到HTML
表单的隐藏域中。当表单提交时,隐藏域的值也同时提交到服务器端。隐藏域技术只在网页有表单时有效。隐藏域技术相对于 URL
重写的优势在于:没有字符数限制,同时无须额外的编码。但隐藏域技术同URL重写
一样,不适合跨越多个界面。
Demo
完整代码
User类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package session.management.hiddenfields; public class User { String id; String name; String city; String sex; public String getId() { return id; } public void setId(String 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; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
|
这里的User类用来存放我们要操作的数据.
UserServlet类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
| package session.management.hiddenfields; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet( name = "UserServlet", // 这些URL都用当前这个Servlet来处理 urlPatterns = {"/showUsers", "/editUser", "/updateUser", "/addUser"} ) public class UserServlet extends HttpServlet { ArrayList<User> userList; private static final long serialVersionUID = 2L; private User findUserById(String id) { for (User person : userList) { if (person.getId().equals(id)) { return person; } } return null; } @Override public void init() throws ServletException { userList = new ArrayList<User>(); User p1 = new User(); User p2 = new User(); p1.setId("1"); p1.setName("小明"); p1.setCity("南京"); p1.setSex("男"); userList.add(p1); p2.setId("2"); p2.setName("小王"); p2.setCity("南京"); p2.setSex("男"); userList.add(p2); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); response.setHeader("Content-type", "text/html;charset=UTF-8"); String url = request.getRequestURI(); if (url.endsWith("/showUsers")) { showUserList(response); } else if (url.endsWith("/editUser")) { sendEditForm(request, response); } else if (url.endsWith("/addUser")) { sendAddForm(request, response); } } private void sendAddForm(HttpServletRequest request, HttpServletResponse response) { String html = "<html><head><title>添加User</title><meta charset='utf-8'></head><body><h2>添加User</h2>\r\n" + "<form method='post' action='addUser'><table><tbody>" + "<tr><td style='text-align:right'>编号:</td><td><input type='text' name='id' value='" + (userList.size() + 1) + "' readonly='readonly' title='编号由系统指定,无法修改'></td></tr>\r\n" + "<tr><td style='text-align:right'>姓名:</td><td><input type='text' name='name'></td></tr>\r\n" + "<tr><td style='text-align:right'>城市:</td><td><input type='text' name='city'></td></tr>\r\n" + "<tr><td style='text-align:right'>性别:</td><td><input type='text' name='sex'></td></tr>\r\n" + "<tr><td colspan='2' style='text-align:right'><input type='submit' value='add'></td></tr>\r\n" + "<tr><td colspan='2'><a href='showUsers'>返回用户列表</a></td></tr>" + "</tbody></table></form></body></html>"; responseHTML(response, html); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setHeader("Content-type", "text/html;charset=UTF-8"); String url = request.getRequestURI(); if (url.endsWith("/updateUser")) { updateUser(request, response); } else if (url.endsWith("/addUser")) { addUser(request, response); } } private void addUser(HttpServletRequest request, HttpServletResponse response) { String id = request.getParameter("id"); User user = findUserById(id); if (user == null) { user = new User(); user.setId(id); user.setName(request.getParameter("name")); user.setCity(request.getParameter("city")); user.setSex(request.getParameter("sex")); userList.add(user); } try { response.sendRedirect("showUsers"); } catch (IOException e) { e.printStackTrace(); } } private void updateUser(HttpServletRequest request, HttpServletResponse response) { String id = request.getParameter("id"); User person = findUserById(id); if (person != null) { person.setName(request.getParameter("name")); person.setSex(request.getParameter("sex")); person.setCity(request.getParameter("city")); } try { response.sendRedirect("showUsers"); } catch (IOException e) { e.printStackTrace(); } } private void sendEditForm(HttpServletRequest request, HttpServletResponse response) throws IOException { String id = request.getParameter("id"); PrintWriter writer; writer = response.getWriter(); User person = findUserById(id); if (person != null) { setEditFormByID(response, person); } else { writer.println("<h2>查无此人</h2>"); } } private void setEditFormByID(HttpServletResponse response, User person) { String htmlFirst = "<html>\r\n" + "<head>\r\n" + "<title>更新User</title>\r\n" + "</head>\r\n" + "<meta charset=\"utf-8\">\r\n" + "<body>\r\n" + "<h2>更新User</h2>\r\n" + "<form method='post' action='updateUser'>\r\n" + "<table>"; String htmlTrs = "<tr><td style='text-align:right'>姓名:</td><td><input name='name' value='" + person.getName() + "'></td></tr>\r\n" + "<tr><td style='text-align:right'>城市:</td><td><input name='city' value='" + person.getCity() + "'></td></tr>\r\n" + "<tr><td style='text-align:right'>性别:</td><td><input name='sex' value='" + person.getSex() + "'></td></tr>\r\n" + "<tr><td colspan='2' style='text-align:right'><input type='submit' value='Update'></td></tr>\r\n" + "<tr><td colspan='2'><a href='showUsers'>返回用户列表</a></td></tr>"; String htmlAfter = "</table>\r\n" + "<input type=\"hidden\" name=\"id\" value=\"" + person.getId() + "\">\r\n" + "</form>\r\n" + "</body>\r\n" + "</html>"; String html = htmlFirst + htmlTrs + htmlAfter; responseHTML(response, html); } private void showUserList(HttpServletResponse response) { String HTML = createShowPersonHTML(); responseHTML(response, HTML); } private String createShowPersonHTML() { String htmlBefore = "<html>\r\n" + "<head>\r\n" + "<title>Person</title>\r\n" + "</head>\r\n" + "<body>\r\n" + "<h2>Users:</h2>\r\n" + "<table border=\"1\">\r\n" + "<tr><th>编号</th><th>姓名</th><th>城市</th><th>性别</th><th>操作</th></tr>"; String tr; String htmlAfter = "<tr><td colspan=\"5\" style=\"text-align:right\"><a href=\"addUser\">添加用户</a></td></tr></table>\r\n" + "</body>\r\n" + "</html>"; StringBuffer sb = new StringBuffer(htmlBefore); for (int i = 0, lenght = userList.size(); i < lenght; i++) { User person = userList.get(i); tr = "<tr>\r\n" + "<td>" + person.getId() + "</td>\r\n" + "<td>" + person.getName() + "</td>\r\n" + "<td>" + person.getCity() + "</td>\r\n" + "<td>" + person.getSex() + "</td>\r\n" + "<td>\r\n" + "<a href=\"editUser?id=" + person.getId() + "\">编辑</a>\r\n" + "</td>\r\n" + "</tr>"; sb.append(tr); } sb.append(htmlAfter); return sb.toString(); } private void responseHTML(HttpServletResponse response, String HTML) { PrintWriter writer; try { writer = response.getWriter(); writer.write(HTML); } catch (IOException e) { e.printStackTrace(); } } }
|
代码详解
URL映射
1 2 3 4 5 6
| @WebServlet( name = "PersonServlet", // 这些URL都用当前这个Servlet来处理 urlPatterns = {"/showUsers", "/editUser", "/updateUser"} )
|
这里为这个Servlet映射了三个URL,分别用于展示数据http://localhost:8080/SessionManagement/showUsers,修改数据,展示更新后的数据。
初始化数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ArrayList<User> userList; private static final long serialVersionUID = 2L;
@Override public void init() throws ServletException { userList = new ArrayList<User>(); User p1 = new User(); User p2 = new User(); p1.setId("1"); p1.setName("小明"); p1.setCity("南京"); p1.setSex("男"); userList.add(p1); p2.setId("2"); p2.setName("小王"); p2.setCity("南京"); p2.setSex("男"); userList.add(p2); }
|
这里首先声明了一个装有User
对象的容器,当用户第一次请求页面时,Tomcat
调用init()
方法,init()
方法,创建并初始化两个User
对象,并把它们放到userList
中。
工具方法
根据用户id获取该用户对象的引用
1 2 3 4 5 6 7 8 9
| private User findUserById(String id) { for (User person : userList) { if (person.getId().equals(id)) { return person; } } return null; }
|
这个方法可以根据用户的id
,从userList中查找User,如果没有将返回null.
输出HTML字符串到响应对象中
1 2 3 4 5 6 7 8 9 10 11
| private void responseHTML(HttpServletResponse response, String HTML) { PrintWriter writer; try { writer = response.getWriter(); writer.write(HTML); } catch (IOException e) { e.printStackTrace(); } }
|
显示所有用户数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); response.setHeader("Content-type", "text/html;charset=UTF-8"); String url = request.getRequestURI(); if (url.endsWith("/showUsers")) { showUserList(response); } else if (url.endsWith("/editUser")) { sendEditForm(request, response); } else if (url.endsWith("/addUser")) { sendAddForm(request, response); } } private void showUserList(HttpServletResponse response) { String HTML = createShowPersonHTML(); responseHTML(response, HTML); } private String createShowPersonHTML() { String htmlBefore = "<html>\r\n" + "<head>\r\n" + "<title>Person</title>\r\n" + "</head>\r\n" + "<body>\r\n" + "<h2>Users:</h2>\r\n" + "<table border=\"1\">\r\n" + "<tr><th>编号</th><th>姓名</th><th>城市</th><th>性别</th><th>操作</th></tr>"; String tr; String htmlAfter = "<tr><td colspan=\"5\" style=\"text-align:right\"><a href=\"addUser\">添加用户</a></td></tr></table>\r\n" + "</body>\r\n" + "</html>";
StringBuffer sb = new StringBuffer(htmlBefore); for (int i = 0, lenght = userList.size(); i < lenght; i++) { User person = userList.get(i); tr = "<tr>\r\n" + "<td>" + person.getId() + "</td>\r\n" + "<td>" + person.getName() + "</td>\r\n" + "<td>" + person.getCity() + "</td>\r\n" + "<td>" + person.getSex() + "</td>\r\n" + "<td>\r\n" + "<a href=\"editUser?id=" + person.getId() + "\">编辑</a>\r\n" + "</td>\r\n" + "</tr>"; sb.append(tr); } sb.append(htmlAfter); return sb.toString(); }
|
显示效果如下:
其中超链接HTML代码如下:
1 2 3
| <a href="editUser?id=1">编辑</a> <a href="editUser?id=2">编辑</a> <a href="addUser">添加用户</a>
|
这是前面介绍的URL重写技术
,因为前面路径省略,浏览器会发给父路径http://localhost:8080/SessionManagement/
,最终得到URL为:http://localhost:8080/SessionManagement/editUser?id=1
,点击这个URL可以可以进入修改页面。
修改用户数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| private void sendEditForm(HttpServletRequest request, HttpServletResponse response) throws IOException { String id = request.getParameter("id"); PrintWriter writer; writer = response.getWriter(); User person = findUserById(id); if (person != null) { setEditFormByID(response, person); } else { writer.println("<h2>查无此人</h2>"); } } private void setEditFormByID(HttpServletResponse response, User person) { String htmlFirst = "<html>\r\n" + "<head>\r\n" + "<title>更新User</title>\r\n" + "</head>\r\n" + "<meta charset=\"utf-8\">\r\n" + "<body>\r\n" + "<h2>更新User</h2>\r\n" + "<form method='post' action='updateUser'>\r\n" + "<table>"; String htmlTrs = "<tr><td style='text-align:right'>姓名:</td><td><input name='name' value='" + person.getName() + "'></td></tr>\r\n" + "<tr><td style='text-align:right'>城市:</td><td><input name='city' value='" + person.getCity() + "'></td></tr>\r\n" + "<tr><td style='text-align:right'>性别:</td><td><input name='sex' value='" + person.getSex() + "'></td></tr>\r\n" + "<tr><td colspan='2' style='text-align:right'><input type='submit' value='Update'></td></tr>\r\n" + "<tr><td colspan='2'><a href='showUsers'>返回用户列表</a></td></tr>"; String htmlAfter = "</table>\r\n" + "<input type=\"hidden\" name=\"id\" value=\"" + person.getId() + "\">\r\n" + "</form>\r\n" + "</body>\r\n" + "</html>"; String html = htmlFirst + htmlTrs + htmlAfter; responseHTML(response, html); }
|
假设用户点击的是第一个超链接,也就是通过http://localhost:8080/SessionManagement/editUser?id=1这个URL
访问。
此时,Tomcat将调用doGet方法,doGet方法调用sendEditForm方法,该根据Id
找出一个User
对象,然后doGet调用setEditFormByID
这个方法,把User对象中的数据填入表单,封装成HTML
,发送给浏览器显示,用户在浏览器中修改表单中的数据即可完成修改,然后点击update
按钮进行更新。如下图所示:
在服务器发送HTML的时候在表单之中偷偷塞了一个如下的隐藏域:
1
| <input type="hidden" name="id" value="1">
|
这个隐藏域存放用户的id
信息,这样当用户提交表单的时候,服务器就可根据这id信息,知道要修改的是哪个User对象的数据。
还是有就是表达的两个属性:
1
| <form method="post" action="updateUser">
|
这表明提交方法为post
方法,提交给/updateUser
这个URL。提交后Tomcat将调用/updateUser
这个URL对应的Servlet的doPost()
方法。
服务器端更新数据
假设用户在表单中修改好了数据,然后点击update按键提交,调用的方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8");
response.setHeader("Content-type", "text/html;charset=UTF-8"); String url = request.getRequestURI(); if (url.endsWith("/updateUser")) { updateUser(request, response); } else if (url.endsWith("/addUser")) { addUser(request, response); } } private void updateUser(HttpServletRequest request, HttpServletResponse response) { String id = request.getParameter("id"); User person = findUserById(id); if (person != null) { person.setName(request.getParameter("name")); person.setSex(request.getParameter("sex")); person.setCity(request.getParameter("city")); } try { response.sendRedirect("showUsers"); } catch (IOException e) { e.printStackTrace(); } }
|
因为表单提交方式为post,所以Tomcat调用doPost()方法来做出响应。doPost()中做了写编码相关的设置,然后调用updateUser
方法,updateUser
这个方法,先获取id参数。然后根据id参数找到要修改的User对象。使用文本框中修改过的值更新这个对象的内容。这样就完成了更新数据的操作,最后请求重定向到showUsers
这个URL
上,也就是显示主界面
显示效果如下:
添加用户
在主界面中点击最下方的超链接<a href="addUser">添加用户</a>
可以添加一个用户,浏览器请求http://localhost:8080/SessionManagement/addUser这个URL响应,这是一个get请求.Tomcat调用doGet方法响应,doGet方法根据请求的URL,调用sendAddForm方法,这个方法发给浏览器一个表单。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| private void sendAddForm(HttpServletRequest request, HttpServletResponse response) { String html = "<html><head><title>添加User</title><meta charset='utf-8'></head><body><h2>添加User</h2>\r\n" + "<form method='post' action='addUser'><table><tbody>" + "<tr><td style='text-align:right'>编号:</td><td><input type='text' name='id' value='" + (userList.size() + 1) + "' readonly='readonly' title='编号由系统指定,无法修改'></td></tr>\r\n" + "<tr><td style='text-align:right'>姓名:</td><td><input type='text' name='name'></td></tr>\r\n" + "<tr><td style='text-align:right'>城市:</td><td><input type='text' name='city'></td></tr>\r\n" + "<tr><td style='text-align:right'>性别:</td><td><input type='text' name='sex'></td></tr>\r\n" + "<tr><td colspan='2' style='text-align:right'><input type='submit' value='add'></td></tr>\r\n" + "<tr><td colspan='2'><a href='showUsers'>返回用户列表</a></td></tr>" + "</tbody></table></form></body></html>"; responseHTML(response, html); }
|
需要注意的是id信息,我这里放在隐藏域中:
1
| <input type="hidden" name="id" value="3">
|
需要注意的是表单的属性:
1
| <form method='post' action='addUser'>
|
这表明表单将会发送给addUser
这个URL,虽然还是调用的这个URL,但是这次是post请求,而不是get请求。
填写表单如下:
所以Tomcat会调用doPost方法来响应。doPost根据请求中的URL,调用addUser
方法,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| private void addUser(HttpServletRequest request, HttpServletResponse response) { String id = request.getParameter("id"); User user = findUserById(id); if (user == null) { user = new User(); user.setId(id); user.setName(request.getParameter("name")); user.setCity(request.getParameter("city")); user.setSex(request.getParameter("sex")); userList.add(user); } try { response.sendRedirect("showUsers"); } catch (IOException e) { e.printStackTrace(); } }
|
这个方法,把表单中提交的数据转换成User对象,然后添加到userList中保存。最后重定向到showUser
这个URL去显示添加的效果,如下所示:
小结
这个demo就到这里了,本来我还想搞个删除的功能,但是懒得搞了,先这样。