会话可以简单的理解为客户端用户打开一个浏览器,点击多个超链接,访问服务器多个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("&nbsp;<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重写和表单隐藏域)的更多相关文章

  1. jquery.validate 使用--验证表单隐藏域

    jQuery validate很不错的一个jQuery表单验证插件.升级到了1.9版的后,发现隐藏表单域验证全部失效,特别是在jquery.ui.tabs.min.js构造的Tabs里的验证. 是因为 ...

  2. 表单隐藏域与display:none

    有时候前端进行表单填写是分步骤的,每一步的时候其他步骤相关的表单视图不可见: 针对"不可见",以下有两种处理方式: ①display:none 这种方式呢,比较简单,就是将三个步骤 ...

  3. Servlet会话管理三(HttpSession)

    Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象.由于Session为浏览器用户所独享,所以用户在访问服务器的web资源时,可以把各自的数 ...

  4. 【ASP.NET Web API教程】5.2 发送HTML表单数据:URL编码的表单数据

    原文:[ASP.NET Web API教程]5.2 发送HTML表单数据:URL编码的表单数据 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...

  5. Servlet之会话(Session)以及会话追踪技术(Cookie),(URL重写)和(隐藏表单域)

    Session 什么是会话? 会话: Web应用中的会话 指的是一个客户端浏览器与Web服务器之间连续发生的一系列请求和响应的过程 会话状态: Web服务器和浏览器在会话的过程中产生的状态信息 作用: ...

  6. servlet 会话管理

    一.URL 重写 URL 重写是一种会话跟踪技术,它将一个或多个token添加到URL的查询字符串中,每个token通常为 key=value形式,如下: url?key-1=value-1& ...

  7. Java Web(三) Servlet会话管理

    会话跟踪 什么是会话? 可简单理解为,用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭服务器,整个过程称为一个会话.从特定客户端到服务器的一系列请求称为会话.记录会话信息的技术称 ...

  8. Servlet会话管理二(Cookie)

    Cookie是在HTTP协议下,将服务器传递给浏览器的的少量信息保存到浏览器客户端的一种技术,通过这种技术,即使在浏览器被关闭或链接中断的情况下,用户仍可以维护Cookie中的数据. Cookie是经 ...

  9. Java EE.Servlet.会话管理

    一次会话是从客户打开浏览器开始到关闭浏览器结束.记录会话信息的技术称为会话跟踪.常见的会话跟踪技术有Cookie.URL重写和隐藏表单域. 1.Cookie Cookie是一小块可以嵌入到HTTP请求 ...

随机推荐

  1. sass 使用clac的问题

    最后在github的issue中找到了方法,要想在sass的calc中使用变量,必须对这个变量使用sass的插值方法(#{$variable}). 所以把代码改正下面的形式就可以了: width: c ...

  2. CSS Media Query

    [CSS Media Query] CSS Media Queries are a feature in CSS3 which allows you to specify when certain C ...

  3. [疯狂Java]JDBC:PreparedStatement预编译执行SQL语句

    1. SQL语句的执行过程——Statement直接执行的弊病: 1) SQL语句和编程语言一样,仅仅就会普通的文本字符串,首先数据库引擎无法识别这种文本字符串,而底层的CPU更不理解这些文本字符串( ...

  4. 算法之LOWB三人组之插入排序

    插入排序 思想:类似于抽扑克牌,共有8张扑克牌,手里默认有一张,桌面上有7张,我们每次从桌面上抽一张和手里的牌进行比较,如果比手里的牌大,则直接放到手里的牌的后面,如果比手里的牌小,则放到手里的牌的前 ...

  5. linux 查看端口占用

    参考 https://www.cnblogs.com/wangtao1993/p/6144183.html lsof -i:8000

  6. oracle数据库连接不上

    Oracle数据库1521端口telnet不通 现象:服务器的ip地址可以ping通,但是安装oracle过程中的指定的“1521”端口telnet不通过 解决办法:1.确保防火墙对1521端口开启: ...

  7. 【Nodejs】ExpressのRequestとResponseの内容

    Request 对象 - request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性.常见属性有: req.app:当callback为外部文件时,用req.ap ...

  8. PERL 正则表达式简介

    来源:脚本之家 网址:http://www.jb51.net/article/17429.htm 一.简介 二.匹配操作符 三.模式中的特殊字符 1.字符+ 2.字符 []和[^] 3.字符 *和? ...

  9. rancher2 挂载ceph-rbd

    一-创建ceph-secret.yml文件 RBD的KEY查看 ceph auth list 复制 client.admin 的key 并使用base64加密 创建ceph-secret.yml ku ...

  10. 第三章 列表(d)选择排序