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内容。

ios session是什么 session ipa是什么意思_ios 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的实现原理如下:

 

ios session是什么 session ipa是什么意思_java_02

因为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>




没有高深的知识,没有进阶的技巧,万丈高楼平地起~!