Servlet会话管理一(URL重写和表单隐藏域)
会话可以简单的理解为客户端用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器的整个过程称为一个会话。即一个客户端用户和服务器端进行通讯的过程,也是客户端和服务器端之间的数据传输过程。
HTTP协议的无状态性导致web服务器无法区分一个HTTP请求是否为第一次访问,因此需要程序必须能管理会话,并为每个用户保存其与服务器交互过程中产生的数据。
会话管理就是管理浏览器客户端和服务器端之间会话过程中产生的数据。
Servlet有4中不同的状态保持技术:
-- URL重写(token-based会话跟踪技术)
-- 表单隐藏域(仅当网页中有表单时使用) <input type="hidden" name="field_name" value="value">
-- cookies(客户端技术,数据保存在客户端)
-- HTTPSession(服务器端技术,数据保存在服务器端)
URL重写 (token-based会话跟踪技术)
将一个或多个token添加到URL的查询字符串中,每个token通常为 key=value 的形式。其中,URL和token之间用 ? 分隔,token之间用 & 分隔。
URL重写仅适合于信息仅在少量页面间传递,且信息本身不敏感的情况
数据通过URL后面的token传递到下一个页面,在下一个页面(即下一个http请求)中,通过获取request.getParameter(name)获取tonken的值,从而保证了数据在不同页面间的传递 。
请表单的提交方式为get时,表单中的参数也会显示的出现在URL后面
package app02a.urlrewriting; 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; /**
* Servlet implementation class Top10Servlet
*/
@WebServlet(name = "Top10Servlet", urlPatterns = { "/top10" })
public class Top10Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private List<String> londonAttractions;
private List<String> parisAttractions; public Top10Servlet() {
super();
}
@Override
public void init() throws ServletException { // 用户第一次访问时,Tomcat初始化Servlet,init()方法被调用。
londonAttractions = new ArrayList<String>(10); // 赋值类的成员变量
londonAttractions.add("1.Buckingham Palace");
londonAttractions.add("2.Lodon Eye");
londonAttractions.add("3.British Museum");
londonAttractions.add("4.National Gallery");
londonAttractions.add("5.Big Ben");
londonAttractions.add("6.Tower of London");
londonAttractions.add("7.Natural History Museum");
londonAttractions.add("8.Canary Wharf");
londonAttractions.add("9.2012 Olympic Park");
londonAttractions.add("10.ST Paul's Cathedral"); parisAttractions = new ArrayList<String>(10); // 赋值类的成员变量
parisAttractions.add("1.Eiffel Tower");
parisAttractions.add("2.Notre Dame");
parisAttractions.add("3.The Louver");
parisAttractions.add("4.Champs Elysees");
parisAttractions.add("5.Arc de Triomphe");
parisAttractions.add("6.Sainte Chapelle Church");
parisAttractions.add("7.Les Invalides");
parisAttractions.add("8.Muess d'Orsay");
parisAttractions.add("9.Montmarte");
parisAttractions.add("10.Sacre Couer Basilica");
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String city = request.getParameter("city"); // 获取token的值,该token随URL传递过来
if (city != null && (city.equals("london") || city.equals("paris"))) {
showAttractions(request, response, city);
} else {
showMainPage(request, response);
}
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
private void showMainPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter(); // 向客户端发送信息
writer.println("<html>");
writer.println("<head>");
writer.println("<title>Top10 Tourist Atrractions</title>");
writer.println("</head>");
writer.println("<body>");
writer.println("Please select a city:<br />");
writer.println("<a href='?city=london'>London</a><br />"); // 相对url,由 http://localhost:8080/top10/top10
writer.println("<a href='?city=paris'>Paris</a><br />"); // 变为 http://localhost:8080/top10/top10?city=london
writer.println("</body>"); // 并将后者发送到服务器
writer.println("</html>");
}
private void showAttractions(HttpServletRequest request, HttpServletResponse response, String city) throws ServletException, IOException {
int page = 1;
String pageParameter = request.getParameter("page"); // 获取token的值
if (pageParameter != null) {
try {
page = Integer.parseInt(pageParameter);
}catch(NumberFormatException e) {
e.printStackTrace();
}
if (page > 2) {
page = 1;
}
}
List<String> attractions = null;
if (city.equals("london")) {
attractions = londonAttractions;
} else {
attractions = parisAttractions;
}
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<head>");
writer.println("<title>Top 10 Tourist Attractions</title>");
writer.println("</head>");
writer.println("<body>");
writer.println("<a href='top10'>Select City</a>"); // 相对url 由 http://localhost:8080/top10/top10?city=london
writer.println("<hr />"); // 变为 http://localhost:8080/top10/top10
writer.println("Page " + page);
writer.println("<hr />");
int start = page * 5 -5;
for (int i = start; i < start + 5; i++) {
writer.println(attractions.get(i) + "<br />");
}
writer.print("<hr style='color:blue' />");
writer.println("<a href='?city=" + city + "&page=1'>Page 1</a>"); // 由 localhost:8080/top10/top10?city=london 变为 localhost:8080/top10/top10?city=london&page=1
writer.println(" <a href='?city=" + city + "&page=2'>Page 2</a>"); // 由 localhost:8080/top10/top10?city=london 变为 localhost:8080/top10/top10?city=london&page=2
writer.println("</body>");
writer.println("</html>");
}
}
表单隐藏域(仅当网页中有表单时有效)
使用隐藏域来保存会话过程中的数据是将值放到HTML表单的隐藏域中。当表单提交时,隐藏域的值也同时提交到服务器端。
<input type="hidden" name="field_name" value="value">
该技术较URL重写相比,没有字符的限制,同时无需额外编码,但也不适合跨越多个页面。
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; @WebServlet(name = "CustomerServlet", urlPatterns = { "/customer", "/editCustomer", "/updateCustomer" })
public class CustomerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private List<Customer> customers = new ArrayList<Customer>(); // 类的成员变量 public CustomerServlet() {
super();
} @Override
public void init() throws ServletException { // 初始化两个数据,正常情况下,这些数据应该存储在数据库中
Customer customer1 = new Customer();
customer1.setId(1);
customer1.setName("Donal D.");
customer1.setCity("Miami");
customers.add(customer1); Customer customer2 = new Customer();
customer2.setId(2);
customer2.setName("Micky 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>");
writer.println("<head>");
writer.println("<title>Customers</title>");
writer.println("</head>");
writer.println("<body>");
writer.println("<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>)</li>"); // URL重写方式
}
writer.println("</ul>");
writer.println("</body>");
writer.println("</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")); // 将String类型装换成int类型
} catch (NumberFormatException e) {
e.printStackTrace();
}
Customer customer = getCustomer(customerId);
if (customer != null) {
writer.println("<html>");
writer.println("<head>");
writer.println("<title>Edit Customer</title>");
writer.println("</head>");
writer.println("<body>");
writer.println("<h2>Edit Customer</h2>");
writer.println("<form method='post' action='updateCustomer'>");
writer.println("<input type='hidden' name='id' value='" + customerId + "' />"); // 隐藏域 用于传递数据
writer.println("<table>");
writer.println("<tr>");
writer.println("<td>Name:</td>");
writer.println("<td><input name='name' value='" + customer.getName().replaceAll("'", "'") + "' /></td>"); //'编码单引号
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>City:</td>");
writer.println("<td><input name='city' value='" +customer.getCity().replaceAll("'", "'") + "' /></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td colspan='2' style='text-align:right'><input type='submit' value='Update' /></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td colspan='2'><a href='customer'>Customer List</a></td>");
writer.println("</tr>");
writer.println("</table>");
writer.println("</form>");
writer.println("</body>");
writer.println("</html>");
} else {
writer.println("No customer found!");
}
} protected 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);
}
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int customerId = 0;
try {
customerId = Integer.parseInt(request.getParameter("id")); // 获取隐藏域中的值
} catch (NumberFormatException e) {
e.printStackTrace();
}
Customer customer = getCustomer(customerId);
if (customer != null) {
customer.setName(request.getParameter("name"));
customer.setCity(request.getParameter("city"));
}
sendCustomerList(response);
}
}
cookies(客户端技术,数据保存在客户端)
Servlet会话管理一(URL重写和表单隐藏域)的更多相关文章
- jquery.validate 使用--验证表单隐藏域
jQuery validate很不错的一个jQuery表单验证插件.升级到了1.9版的后,发现隐藏表单域验证全部失效,特别是在jquery.ui.tabs.min.js构造的Tabs里的验证. 是因为 ...
- 表单隐藏域与display:none
有时候前端进行表单填写是分步骤的,每一步的时候其他步骤相关的表单视图不可见: 针对"不可见",以下有两种处理方式: ①display:none 这种方式呢,比较简单,就是将三个步骤 ...
- Servlet会话管理三(HttpSession)
Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象.由于Session为浏览器用户所独享,所以用户在访问服务器的web资源时,可以把各自的数 ...
- 【ASP.NET Web API教程】5.2 发送HTML表单数据:URL编码的表单数据
原文:[ASP.NET Web API教程]5.2 发送HTML表单数据:URL编码的表单数据 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...
- Servlet之会话(Session)以及会话追踪技术(Cookie),(URL重写)和(隐藏表单域)
Session 什么是会话? 会话: Web应用中的会话 指的是一个客户端浏览器与Web服务器之间连续发生的一系列请求和响应的过程 会话状态: Web服务器和浏览器在会话的过程中产生的状态信息 作用: ...
- servlet 会话管理
一.URL 重写 URL 重写是一种会话跟踪技术,它将一个或多个token添加到URL的查询字符串中,每个token通常为 key=value形式,如下: url?key-1=value-1& ...
- Java Web(三) Servlet会话管理
会话跟踪 什么是会话? 可简单理解为,用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭服务器,整个过程称为一个会话.从特定客户端到服务器的一系列请求称为会话.记录会话信息的技术称 ...
- Servlet会话管理二(Cookie)
Cookie是在HTTP协议下,将服务器传递给浏览器的的少量信息保存到浏览器客户端的一种技术,通过这种技术,即使在浏览器被关闭或链接中断的情况下,用户仍可以维护Cookie中的数据. Cookie是经 ...
- Java EE.Servlet.会话管理
一次会话是从客户打开浏览器开始到关闭浏览器结束.记录会话信息的技术称为会话跟踪.常见的会话跟踪技术有Cookie.URL重写和隐藏表单域. 1.Cookie Cookie是一小块可以嵌入到HTTP请求 ...
随机推荐
- spring注解之@Lazy
今天主要从以下几方面来介绍一下@Lazy注解 @Lazy注解是什么 @Lazy注解怎么使用 1,@Lazy注解是什么 @Lazy注解用于标识bean是否需要延迟加载,源码如下: @Target({ ...
- Integer 原码解读
有一天,突然发现,阅读原码可以发现很多有趣的东西.在Java中,我们知道很多东西都是封装好的,拿来即用,当你有一天去研究它拿来的东西是如何具体操作的,将会是非常有趣的事情. 在上一篇研究HashMap ...
- oracle授予调用存储过程权限
参考 https://blog.csdn.net/h254532693/article/details/45364317 grant execute on PROCEDURENAME to USERN ...
- Android studio 安装中遇到一些问题的解决办法,分享一下
从eclipse转到android studio也是很无耐,刚开始总是会遇到很多难题,但是都不要轻言放弃. 以下是我遇到的问题,并通过搜索引擎找到的解决办法,善用工具,善用头脑,勿为伸手之人. And ...
- dedecms 后台修改系统设置,但是config.cache.inc.php文件不能写入
fopen居然返回false,既不是目录或文件权限相关问题,也不是文件路径问题(相对路径.绝对路径)等,更不是打开文件的模式问题(r,w,a等).网上搜了一会,说到返回false的原因无非都是上面三种 ...
- as3.0复制影片简介(自我复制的三种形式)
//mc是被复制影片简介的实例名,(===在库中找到mc影片简介,右击“属性”,点击“为actionscript导出”,选中确定即可===这个是重点) var newSprite:Sprite=mc; ...
- http://www.bugku.com:Bugku——Easy_vb
之前复习了汇编等知识,这是人生中第一个逆向题目,嘻嘻. 启程. 对于执行文件,首先需要看它是32位还是64位的.这里了解到静态工具IDA的启动程序为idaq.exe和idaq64.exe( ...
- vue 父子组件相互传参
转自https://blog.csdn.net/u011175079/article/details/79161029 子组件: <template> <div> <di ...
- c#: Noto Sans字体如何支持韩文
1.源起: VCU10项目,使用了Noto Sans字体,的确漂亮.但验证在win7下,其显示韩文为乱码,颇为头痛. 其界面显示如图: 度娘之,得Noto Sans又有CJK字体,顾名思义,其为支持中 ...
- day 14 项目目录规范; time ; logging
import sys print(sys.modules) 程序一运行,解释器将里面的所有内容全部加载到内存 项目目录规范: 代码不可能全部只写在一个文件,十几万行代码,调整,修改都很不方便. 所 ...