1. Session概述

1.1. 什么是Session

Session一般译为会话,是解决Http协议的无状态问题的方案,可以将一次会话中的数据存储在服务器端的内存中,保证在下一次的会话中可以使用。

在客户端浏览器第一次向服务器端发送请求时,服务器端会为这个客户端创建独有的Session,并具有唯一的Session ID,存储在服务器端的内存中。在客户端第二次访问服务器端时,会携带Session ID在请求中,服务器端会根据Session ID查找对应的Session信息,进行进一步地操作。

在JavaEE中提供了javax.servlet.http.HttpSession接口,通过该接口可以将共享的数据内容存储在HttpSession对象中,从而解决Http协议的无状态问题。

1.2. 百度百科

Session直接翻译成中文比较困难,一般都译成时域。在计算机专业术语中,Session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间。以及如果需要的话,可能还有一定的操作空间。

具体到Web中的Session指的就是用户在浏览某个网站时,从进入网站到关闭这个网站所经过的这段时间,也就是用户浏览这个网站所花费的时间。因此从上述的定义中我们可以看到,Session实际上是一个特定的时间概念。

需要注意的是,一个Session的概念需要包括特定的客户端,特定的服务器端以及不中断的操作时间。A用户和C服务器建立连接时所处的Session同B用户和C服务器建立连接时所处的Session是两个不同的Session。

1.3. 维基百科

会话(session)是一种持久网络协议,在用户(或用户代理)端和服务器端之间创建关联,从而起到交换数据包的作用机制,session在网络协议(例如telnet或FTP)中是非常重要的部分。

在不包含会话层(例如UDP)或者是无法长时间驻留会话层(例如HTTP)的传输协议中,会话的维持需要依靠在传输数据中的高级别程序。例如,在浏览器和远程主机之间的HTTP传输中,HTTP cookie就会被用来包含一些相关的信息,例如session ID,参数和权限信息等。

1.4. Session与Cookie的区别

Session与Cookie都是解决Http协议的无状态问题,但是两者之间还是存在一定区别的:

  • Cookie数据存储在客户端的浏览器内存中或本地缓存文件中,Session数据存储在服务器端的内存中。
  • Cookie数据存储安全性较低,Session数据存储安全性较高。
  • Session数据存储在服务器端内存中,访问增多时,降低服务器端性能。而Cookie则不会对服务器端性能造成影响。
  • 单个Cookie存储的数据最大是4KB,一个网站只能存储20个Cookie。Session则没有这个问题。
  • Session在关闭浏览器时失效,而持久Cookie则可以存储更长有效时间。

总的来说,Session与Cookie各有优势,不能简单来说谁更优。具体用法要考虑具体案例情况而定。

2. Session入门

2.1. Session常用API

在JavaEE提供的javax.servlet.http.HttpSession接口,是Web应用程序开发使用Session的接口,该接口提供了很多API方法,而常用的方法有以下几个:

Method Summary

Object

getAttribute(String name) 
          Returns the object bound with the specified name in this session, or null if no object is bound under the name.

Enumeration

getAttributeNames() 
          Returns an Enumeration of String objects containing the names of all the objects bound to this session.

void

removeAttribute(String name) 
          Removes the object bound with the specified name from this session.

void

setAttribute(String name, Object value) 
          Binds an object to this session, using the name specified.

  • 通过Request对象获得HttpSession对象。
HttpSession session = request.getSession();
  • 通过HttpSession对象设置和获取共享数据内容。
session.setAttribute("name", "longestory");
String name = (String)session.getAttribute("name");

2.2. 第一个Session

掌握了如何获取Session对象及向Session对象中设置及获取共享数据内容,下面我们就来利用HttpSession对象实现数据内容共享。

  • 创建一个Servlet用于向HttpSession对象中存储共享数据内容。
public class FirstServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("name", "longestory");
System.out.println("已经成功向HttpSession对象中存储了共享数据内容name=longestory...");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  • 创建另一个Servlet用于从HttpSession对象中获取储存的共享数据内容。
public class SecondServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter(); HttpSession session = request.getSession();
String name = (String)session.getAttribute("name"); out.println("<h1>你存储的共享数据内容为name="+name+"</h1>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  • 配置Web工程的web.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>app.java.session.FirstServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>SecondServlet</servlet-name>
<servlet-class>app.java.session.SecondServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/first</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SecondServlet</servlet-name>
<url-pattern>/second</url-pattern>
</servlet-mapping>
</web-app>

2.3. Session其他API

在JavaEE的javax.servlet.http.HttpSession接口提供了除常用方法外,还有很多其他方法可供使用:

Method Summary

long

getCreationTime() 
          Returns the time when this session was created, measured in milliseconds since midnight January 1, 1970 GMT.

String

getId() 
          Returns a string containing the unique identifier assigned to this session.

long

getLastAccessedTime() 
          Returns the last time the client sent a request associated with this session, as the number of milliseconds since midnight January 1, 1970 GMT, and marked by the time the container received the request.

int

getMaxInactiveInterval() 
          Returns the maximum time interval, in seconds, that the servlet container will keep this session open between client accesses.

ServletContext

getServletContext() 
          Returns the ServletContext to which this session belongs.

void

invalidate() 
          Invalidates this session then unbinds any objects bound to it.

boolean

isNew() 
          Returns true if the client does not yet know about the session or if the client chooses not to join the session.

void

setMaxInactiveInterval(int interval) 
          Specifies the time, in seconds, between client requests before the servlet container will invalidate this session.

  • String getId():获取sessionId;
  • long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;
  • long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;
  • boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新;
  • int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
  • void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;
  • void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId。

下面我们通过一个Servlet将上述中的一些方法进行测试,这里理解性记忆就好,后面案例中用到哪个方式再具体掌握。

  • 创建一个Servlet用于测试HttpSession对象的方法。
public class ThreeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Calendar calendar = Calendar.getInstance(); HttpSession session = request.getSession();
System.out.println("Session的ID为"+session.getId()); calendar.setTimeInMillis(session.getCreationTime());
System.out.println("Session的创建时间为"+formatter.format(calendar.getTime())); calendar.setTimeInMillis(session.getLastAccessedTime());
System.out.println("Session的最后活动时间为"+formatter.format(calendar.getTime())); System.out.println("当前Session是否为新的?"+session.isNew());
System.out.println("Session的默认活动时间为"+session.getMaxInactiveInterval()/60+"分钟");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  • 配置Web工程的web.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<servlet>
<servlet-name>ThreeServlet</servlet-name>
<servlet-class>app.java.session.ThreeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ThreeServlet</servlet-name>
<url-pattern>/three</url-pattern>
</servlet-mapping>
</web-app>

2.4. Servlet三大域对象

现在掌握了HttpSession对象的基本使用方法,到目前为止,Servlet的三大域对象都已经掌握。Servlet的三大域对象分别为HttpServletRequest对象、ServletContext对象及HttpSession对象:

  • HttpServletRequest:一个请求创建一个request对象,所以在同一个请求中可以共享request,例如一个请求从AServlet转发到BServlet,那么AServlet和BServlet可以共享request域中的数据;
  • ServletContext:一个应用只创建一个ServletContext对象,所以在ServletContext中的数据可以在整个应用中共享,只要不启动服务器,那么ServletContext中的数据就可以共享;
  • HttpSession:一个会话创建一个HttpSession对象,同一会话中的多个请求中可以共享session中的数据。

3. Session详解

3.1. Session的实现原理

通过HttpSession对象实现了在多次会话中共享数据内容,HttpSession对象底层到底是如何实现这样的效果?下面我们来讨论一下。

  • 利用MyEclipse工具的Debug模式进行调试代码,在request.getSession()处打上断点。
  • Debug模式启动Tomcat服务器,并访问对应的Servlet,抓取获取的Session内容。

会发现实际得到的是org.apache.catalina.session.StandardSession对象,该对象是由Tomcat服务器的Session池创建,并为该对象创建唯一的ID值。

  • 通过IE浏览器的HttpWatch工具抓取请求响应协议内容。

会发现服务器端向客户端进行响应时,向客户端发送了一个Cookie信息,具体内容如下:

Set-Cookie: JSESSIONID=0BD17B07E383FA86703B370560E823F2; Path=/11_session/; HttpOnly
  • 客户端再次访问对应Servlet时,通过IE浏览器的HttpWatch工具抓取请求响应协议内容。

会发现客户端向服务器端发送请求时,向服务器端发送了一个Cookie信息,具体内容如下:

Cookie: JSESSIONID=0BD17B07E383FA86703B370560E823F2

通过上述操作,我们会发现在第一次请求时,服务器端向客户端响应Cookie信息,在第二次请求时,客户端向服务器端发送了Cookie信息。进而可以总结出Session的实现原理如下:

因为Session使用的是会话Cookie,所以当浏览器关闭后,Session会失效。重新打开浏览器访问对应Servlet时,服务器端会重新创建Session对象。可以使用持久Cookie来延长Session的有效时间。

3.2. 禁用Cookie后的Session

通过Session的实现原理可以知道,Session的实现是基于Cookie的。如果浏览器禁用Cookie的话,Session是否还是有效的呢?下面我们具体操作来看一看。

  • 打开IE浏览器的“工具”->“Internet选项”->“隐私”选项,阻止所有Cookie。
  • 这时重新启动Tomcat服务器,访问对应的Servlet。

这个问题是否可以解决呢?答案是可以的,可以利用URL重写方式来解决,具体操作如下:

  • 通过Response对象的encodeURL()方法将URL进行重写。
String url = request.getRequestURI();
url = response.encodeURL(url);
response.getWriter().println("<a href='" + url + "'>second</a>");

禁用Cookie解决Session的问题,这种解决方案是具有理论意义的,但不具备实际意义。因为大部分的网站都是基于Cookie完成数据共享的,例如京东网站或淘宝网站等。如果浏览器禁用Cookie,网站会提示相关信息。

3.3. Session的生命周期

关于Sessioin的生命周期,在之前的内容都有学习到,只是没有专门归纳总结。下面总结一下Session的生命周期,主要是Session的创建和销毁。

  • Session的创建:在客户端第一次向服务器端发送请求,并执行request.getSession()方法时。
  • Session的销毁:
    • 不正常关闭浏览器时。(正常关闭浏览器,Session信息被序列化到硬盘中,保存在Tomcat服务器安装目录/work目录)
    • Session信息过期时(Session默认的有效时间为30分钟)。

      可以利用setMaxInactiveInterval(int interval)方法设置Session的有效时间。

    • 在服务器端程序中执行session.invalidate()方法,手动销毁Session对象。

4. Session案例

4.1. 商品购物车案例

利用Session实现商品购物车的逻辑功能,具体操作如下:

  • 创建一个JSP页面用于显示商品信息。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.Set"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'show.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<!-- 商品列表 -->
<h1>商品列表</h1>
Java编程思想<a href="/session/show?id=1">购买</a><br>
Java设计模式<a href="/session/show?id=2">购买</a><br>
Java语言入门<a href="/session/show?id=3">购买</a><br>
Oracle数据库<a href="/session/show?id=4">购买</a><br>
MySQL数据库<a href="/session/show?id=5">购买</a><br>
<!-- 购物车记录 -->
<h1>购物车记录</h1>
<h2><a href="/session/clear">清空购物车</a></h2>
<%
Map<String,Integer> map = (Map<String,Integer>)request.getSession().getAttribute("cart");
if(map == null){
// 购物车对象不存在
out.println("<h2>购物车无任何商品信息!</h2>");
}else{
// 购物车对象已经存在
Set<String> keySet = map.keySet();
for(String productName: keySet){
int number = map.get(productName);// 购买数量
out.println("商品名称: " + productName +", 购买数量:" + number + "<br/>");
}
}
%>
</body>
</html>
  • 创建一个Servlet用于处理添加购物车的逻辑。
public class ShowServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获得购买商品 id
String id = request.getParameter("id");
// 获得id 对应商品名称
String[] names = { "Java编程思想", "Java设计模式", "Java语言入门", "Oracle数据库", "MySQL数据库" };
String productName = names[Integer.parseInt(id) - 1];
// 判断Session中购物车是否存在
HttpSession session = request.getSession();
Map<String, Integer> cart = (Map<String, Integer>) session.getAttribute("cart");
if (cart == null) {
// 购物车不存在
cart = new HashMap<String, Integer>();
}
// 判断购买商品是否存在于购物车中,商品名称就是map的key
if (cart.containsKey(productName)) {
// 商品已经在购物车中
int number = cart.get(productName);// 取出原来数量
cart.put(productName, number + 1);// 数量+1 放回购物车
} else {
// 商品不在购物车中
cart.put(productName, 1);// 保存商品到购物车,数量为1
}
// 将购物车对象保存Session
session.setAttribute("cart", cart);
// 给用户提示
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("商品已经添加到购物车!<a href='/session/cart/show.jsp'>返回</a>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  • 创建一个Servlet用于处理清空购物车记录的逻辑。
public class ClearServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取购物车Session对象
HttpSession session = request.getSession();
// 删除购物车cart对象
session.removeAttribute("cart");
// 跳转show.jsp
response.sendRedirect("/session/cart/show.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  • 配置Web工程的web.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<servlet>
<servlet-name>ShowServlet</servlet-name>
<servlet-class>app.java.session.ShowServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>ClearServlet</servlet-name>
<servlet-class>app.java.session.ClearServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ShowServlet</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ClearServlet</servlet-name>
<url-pattern>/clear</url-pattern>
</servlet-mapping>
</web-app>

4.2. 一次验证码登录案例

所谓一次验证码,就是验证码生成后,只能使用一次,不管成功或者失败,验证码都将失效。具体实现步骤如下:

  • 创建一个JSP页面用于显示用户登录信息。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'login.jsp' starting page</title>
</head>
<script type="text/javascript">
function change(){
document.getElementById("myimg").src = "/session/checkimg?timeStamp="+new Date().getTime();
}
</script>
<body>
<h1>登陆页面</h1>
<h2 style="color:red;">${requestScope.msg }</h2>
<form action="/11_session/login" method="post">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"/> </td>
</tr>
<tr>
<td>验证码</td>
<td><input type="text" name="checkcode" /> <img src="/session/checkimg" onclick="change();" id="myimg" style="cursor: pointer;"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登陆" /></td>
</tr>
</table>
</form>
</body>
</html>
  • 创建一个Servlet用于生成验证码图片。
public class CheckImgServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 120;
int height = 30;
// 步骤一 绘制一张内存中图片
BufferedImage bufferedImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
// 步骤二 图片绘制背景颜色 ---通过绘图对象
Graphics graphics = bufferedImage.getGraphics();//得到画图对象 - 画笔
// 绘制任何图形之前 都必须指定一个颜色
graphics.setColor(getRandColor(200, 250));
graphics.fillRect(0, 0, width, height);
// 步骤三 绘制边框
graphics.setColor(Color.WHITE);
graphics.drawRect(0, 0, width - 1, height - 1);
// 步骤四 四个随机数字
Graphics2D graphics2d = (Graphics2D) graphics;
// 设置输出字体
graphics2d.setFont(new Font("宋体", Font.BOLD, 18));
String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
Random random = new Random();// 生成随机数
// 为了将验证码保存Session
StringBuffer buffer = new StringBuffer();
// 定义x坐标
int x = 10;
for (int i = 0; i < 4; i++) {
// 随机颜色
graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
// 旋转 -30 --- 30度
int jiaodu = random.nextInt(60) - 30;
// 换算弧度
double theta = jiaodu * Math.PI / 180;
// 生成一个随机数字
int index = random.nextInt(words.length());//生成随机数0到 length-1
// 获得字母数字
char c = words.charAt(index);
// 将生成汉字 加入buffer
buffer.append(c);
// 将c 输出到图片
graphics2d.rotate(theta, x, 20);
graphics2d.drawString(String.valueOf(c), x, 20);
graphics2d.rotate(-theta, x, 20);
x += 30;
}
// 将验证码内容保存session
request.getSession().setAttribute("checkcode_session",buffer.toString());
// 步骤五 绘制干扰线
graphics.setColor(getRandColor(160, 200));
int x1;
int x2;
int y1;
int y2;
for (int i = 0; i < 30; i++) {
x1 = random.nextInt(width);
x2 = random.nextInt(12);
y1 = random.nextInt(height);
y2 = random.nextInt(12);
graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
}
// 将上面图片输出到浏览器 ImageIO
graphics.dispose();// 释放资源
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
/**
* 取其某一范围的color
*
* @param fc
* int 范围参数1
* @param bc
* int 范围参数2
* @return Color
*/
private Color getRandColor(int fc, int bc) {
// 取其随机颜色
Random random = new Random();
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
}
  • 创建一个Servlet用于处理登录验证逻辑。
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获得用户名、密码和 验证码
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkcode = request.getParameter("checkcode");
// 判断验证码是否正确
String checkcode_session = (String) request.getSession().getAttribute("checkcode_session");
request.getSession().removeAttribute("checkcode_session");
if (checkcode_session == null || !checkcode_session.equals(checkcode)) {
// 验证码输入错误
request.setAttribute("msg", "验证码输入错误!");
request.getRequestDispatcher("/login/login.jsp").forward(request,response);
return;
}
// 判断用户名和密码是否正确 ,假设用户名和密码都是admin/admin
if ("admin".equals(username) && "admin".equals(password)) {
// 登陆成功
// 将登陆信息保存session
request.getSession().setAttribute("username", username);
response.sendRedirect("/session/login/welcome.jsp");
} else {
// 登陆失败
request.setAttribute("msg", "用户名或者密码错误!");
     request.getRequestDispatcher("/login/login.jsp").forward(request,response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  • 创建一个JSP页面用于显示欢迎信息。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'welcome.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<h1>登陆后的欢迎页面</h1>
<%
String username = (String)request.getSession().getAttribute("username");
if(username == null){
// 未登陆
out.println("您还未登陆,<a href='/session/login/login.jsp'>去登陆</a>");
}else{
// 已经登陆
out.println("欢迎您,"+username);
}
%>
</body>
</html>

JavaWeb Session的更多相关文章

  1. Javaweb Session机制(有待补充)

    Javaweb Session机制 一.前言 session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话是从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个ses ...

  2. JavaWeb—Session与Cookie

    概念 会话:指从一个浏览器窗口打开到关闭期间的一系列动作(可简单理解为用户开一个浏览器,点击多个链接,访问服务器多个web资源,然后关闭浏览器). HTTP协议是无状态协议:每次连接(比如同一个网站的 ...

  3. JavaWeb Session详解

    代码地址如下:http://www.demodashi.com/demo/12756.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + ## Session的由来 上一篇博文介绍 ...

  4. JavaWeb Session 状态管理

    引言 HTTP 协议是一个无状态的协议,简单理解就是两次请求/响应无法记录或保存状态信息.但是动态 Web 项目开发是需要保存请求状态的,比如用户的登录状态,但 HTTP 协议层不支持状态保存,所以需 ...

  5. JavaWeb -- Session应用实例 -- 随机中文验证码 检验

    注册页面 login.html <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html ...

  6. JavaWeb -- Session实例 -- 自动登录 和 防止表单重复提交(令牌产生器) MD5码

    1. 自动登录 http://blog.csdn.net/xj626852095/article/details/16825659 2. 防止表单重复提交 表单Servlet //负责产生表单 pub ...

  7. javaWeb学习-----session

    一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...

  8. JavaWeb学习总结(十二)——Session

    一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...

  9. (转)JavaWeb学习总结(十三)——使用Session防止表单重复提交

    如何防止表单重复提交 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复 ...

随机推荐

  1. js金钱分割,正则

    ``` var test1 = '1234567890'var format = test1.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"1,234,567, ...

  2. MySQL的order by子句

    1.语法:select 字段列表 from 表名 [where 子句][group by 子句][having 子句][order by 子句]; 注解: 1.默认是从第一条记录开始升序, 2.des ...

  3. Scala之模式匹配(Patterns Matching)

    前言 首先.我们要在一開始强调一件非常重要的事:Scala的模式匹配发生在但绝不仅限于发生在match case语句块中.这是Scala模式匹配之所以重要且实用的一个关键因素!我们会在文章的后半部分具 ...

  4. jQuery整理笔记八----jQuery的Ajax

    Ajax,我一直读的是"阿贾克斯",据当时大学老师讲该读音出处是依据当年风靡欧洲的荷兰足球俱乐部阿贾克斯的名字来的,我认为说法挺靠谱的. jQuery封装了Ajax的交互过程,用户 ...

  5. SVG 与 Canvas:如何选择

    SVG 与 Canvas:如何选择 61(共 69)对本文的评价是有帮助 - 评价此主题   本主题一开始将对 SVG 与 Canvas 进行简要比较,接下来会讨论大量的比较代码示例,如光线跟踪和绿屏 ...

  6. <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

    <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

  7. 原文来自 url get

    w http://www.tuicool.com/articles/BvYbEvR http://36kr.com/p/5069371.html?utm_source=tuicool&utm_ ...

  8. docker logspout

    https://hub.docker.com/r/jplock/rsyslog/ docker pull jplock/rsyslog:8.2.2 docker run -d -p 514:514 j ...

  9. <2013 06 24> 关于Zigbee项目_Munik_TUM_eCar

    (本月)6月4号到德国慕尼黑,参与TUM大学的一个电动车项目组,预计时间3个月. 我的任务是参与wireless的研究,主要就是用无线链接取代有线链接(汽车线缆很多很讨厌). 使用的是TI MP430 ...

  10. ABAP f4帮助输入多个值

    *---------------------------------------------------------------------- * INITIALIZATION *---------- ...