09会话管理

1.会话管理入门

1.1 生活中的会话

我: 你最近有坐船吗?

小明: 有啊,昨天才刚坐

我: 这样啊!!前几天有船沉了,你没事吧?

小明: 不是吧?

1.2 程序中的会话

 一次会话: 打开浏览器 -> 访问服务器  -> 关闭浏览器

 场景1:

 打开浏览器- > 访问网站 -> 登录页面 -> 输入用户名和密码(保存会话信息) -> 提交到后台 -> 校验成功                                                                    

 -> 返回用户首页(看到当前登录的用户名信息。。。)(取出会话信息)-》 关闭浏览器               

 使用什么技术保存这些会话信息????

场景2:

打开浏览器 -> 浏览购物网站 -> 点击“购买” (把商品信息保存下来)->  放入“购物车” -> 关闭浏览器

打开浏览器- > 浏览器购物网站- > 查看"购物车" -> 看到之前的商品信息- >付款购买-关闭浏览器

使用什么技术保存这些商品信息?

会话管理: 管理浏览器与服务器之间的会话过程中产生的会话数据!!!!

思考:

可以使用域对象来保存会话信息????

 context域:

登录: 登录页面( 张三  context.setAttribute("name","张三") )

 -> 访问用户主页(context.getAttribute("name"))

使用context域会覆盖之前的数据

 request域:

登录: 登录页面( 张三  request.setAttribute("name","张三") )  

-> 访问用户主页(request.getAttribute("name"))

使用request域之后,一定要使用转发技术来跳转页面。

1.3 会话管理技术

Cookie技术:会话数据保存在浏览器端。

Session技术: 会话数据保存在服务器端。

2.Cookie技术

2.1 Cookie技术的使用

Cookie对象:

1)创建Cookie对象,用于存储会话数据

new Cookie(java.lang.String name, java.lang.String value)

2)修改Cookie对象

void setPath(java.lang.String uri) 

void setMaxAge(int expiry) 

void setValue(java.lang.String newValue) 

3)把cookie数据发送给浏览器保存

response.addCookie(cookie);

4)浏览器带着cookie访问服务器,服务器接收cookie信息

request.getCookies();

                                              

2.2 Cookie技术原理

1)服务器创建Cookie对象,保存会话数据,把Cookie数据发送给浏览器

  response.addCookie(cookie);     (响应头:set-cookie: name=jacky)

2)浏览器获取cookie数据,保存在浏览器缓存区,然后在下次访问服务器时携带cookie数据

  (请求头: cookie: name=jacky)

 3)服务器获取浏览器发送的cookie数据

  request.getCookies(); 

2.3 Cookie细节

1)cookie的数据类型一定是字符串,如果要发送中文,必须先对中文进行URL加密才可以发送。

2)setPath(path): 修改cookie所在的有效路径。什么是有效路径? 如果把该cookie设置到某个有效路径下,然后当浏览器访问这个有效路径的时候,才会携带cookie数据给服务器。

3)  setMaxAge(整数) : 设置cookie的有效时间

正整数: 表示超过了正整数的数值的时间,cookie就会丢失!!(cookie保存浏览器的缓存                                                                                                                                                                                   目录)单位:秒

负整数: 表示如果浏览器关闭了,cookie就会丢失!(cookie保存浏览器内存)

0    :  表示删除同名的cookie

4)cookie可以有多个,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

package day10Session.cn.jxufe.a_cookie;

import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 * 使用cookie技术
 */
public class CookieDemo1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1)创建Cookie对象,保存会话数据
        // 如果要发送中文,必须先使用URLEncoder进行加密
        String n = URLEncoder.encode("张三", "utf-8");
        Cookie c = new Cookie("name", n);
        Cookie c2 = new Cookie("email", "jacky@qq.com");

        /*
         * 1)设置有效路径。默认情况下,设置当前项目的根目录下
         *    什么是有效路径? 如果把该cookie设置到某个有效路径下,然后当浏览器访问这个有效路径的时候,才会携带这个cookie数据给服务器。
         */
        // c.setPath("/day11");

        /*
         * 2)设置有效时间
         *          正整数: 表示超过了正整数的数值的时间,cookie就会丢失!!(cookie保存浏览器的缓存                                                                                目录)单位:秒
                负整数: 表示如果浏览器关闭了,cookie就会丢失!(cookie保存浏览器内存) (默认情况)
                      0    :  表示删除同名的cookie    
        
         */
        // c.setMaxAge(20); //20秒之后cookie丢失!!!
        c.setMaxAge(-1); // 浏览器关闭cookie丢失!!!(默认情况下)

        // 2)把cookie发送给浏览器.通过响应头携带cookie数据给浏览器(set-cookie)
        // response.setHeader("set-cookie", "name=jacky");
        /*
         *简化版本
         */
        response.addCookie(c);
        response.addCookie(c2);
        // 3)浏览器在下次访问的时候携带了cookie数据,通过请求头发送给服务器(cookie)

        // 4)服务器获取浏览器发送的cookie数据
        // String name = request.getHeader("cookie");
        // System.out.println(name);
        /**
         * 简化版本
         */
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                // cookie的名称
                String name = cookie.getName();
                // 对加密之后的name进行解密
                String value = cookie.getValue();
                value = URLDecoder.decode(value, "utf-8");
                System.out.println(name + "=" + value);
            }
        } else {
            System.out.println("没有cookie信息");
        }
    }

}

package day10Session.cn.jxufe.a_cookie;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 * 删除同名的cookie
 */
public class CookieDemo2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie c = new Cookie("name", "abc");
        c.setMaxAge(0);// 设置时长为0,表示立刻删除

        // 发送cookie
        response.addCookie(c);

        System.out.println("删除成功!");
    }

}

 

2.4 案例-用户上次访问时间

package day10Session.cn.jxufe.a_cookie;

import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 * 案例[上次访问时间]
 */
public class LastTimeServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");

        // 制作了当前时间字符串
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd号 hh时mm分ss秒");
        String curDate = sdf.format(new Date());
        // 获取cookie
        Cookie[] cookies = request.getCookies();

        String lastTime = null;
        if (cookies != null) {
            // 存在cookie,还有继续找是否name为lastTime的cookie
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("lastTime")) {
                    lastTime = cookie.getValue();
                    // 找到了,第n次访问
                    // lastTime保存了上次访问的时间
                    // 对日期字符串进行解密
                    lastTime = URLDecoder.decode(lastTime, "utf-8");
                    // 显示内容给浏览器
                    response.getWriter().write("欢迎再次光临本网站,您上次访问的时间为:" + lastTime + "<br/>当前的时间为:" + curDate);

                    // 更新cookie上次访问的时间
                    curDate = URLEncoder.encode(curDate, "utf-8");
                    cookie.setValue(curDate);
                    response.addCookie(cookie);

                    break;
                }
            }

        }
        // 第一次访问
        if (cookies == null || lastTime == null) {

            // 2)显示到浏览器
            response.getWriter().write("欢迎首次光临本网站,当前时间为:" + curDate);

            // 3)把当前时间保存到cookie中
            // 对中文格式的日期字符串进行加密
            curDate = URLEncoder.encode(curDate, "utf-8");
            Cookie c = new Cookie("lastTime", curDate);

            // 4)把cookie发送给浏览器
            response.addCookie(c);
        }
    }

}

2.5 案例-用户浏览过的商品

 

1.建立包:

2.分包建立文件

<?xml version="1.0" encoding="utf-8"?>
<product-list>
    <product id="1">
        <name>联想笔记本</name>
        <type>LN001</type>
        <price>5000</price>
    </product>
    <product id="2">
        <name>长城笔记本</name>
        <type>CN001</type>
        <price>3000</price>
    </product>
    <product id="3">
        <name>惠普打印机</name>
        <type>HP001</type>
        <price>800</price>
    </product>
    <product id="4">
        <name>戴尔笔记本</name>
        <type>DL001</type>
        <price>6000</price>
    </product>
    <product id="5">
        <name>神州笔记本</name>
        <type>SZ001</type>
        <price>999</price>
    </product>
</product-list>
package day10hist.cn.jxufe.entity;

/*
 * 产品实体对象
 *
 */
public class Product {
    private String id;
    private String name;
    private String type;
    private String price;

    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 getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Product [id=" + id + ", name=" + name + ", price=" + price + ", type=" + type + "]";
    }

}
package day10hist.cn.jxufe.dao;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;

import day10hist.cn.jxufe.entity.Product;
import day10hist.cn.jxufe.util.XMLUtil;

public class ProductDao {
    /**
     * 查看所有商品
     */
    public List<Product> findAll() {
        // 1)读取xml文件
        Document doc = XMLUtil.getDocument();

        // 2)读取所有product标签
        List<Element> proList = doc.getRootElement().elements("product");
        List<Product> list = new ArrayList<Product>();

        // 3)遍历
        for (Element proElem : proList) {
            // 3.1 创建Product对象
            Product p = new Product();
            // 3.2 把prodcut标签内容封装到Product对象中
            p.setId(proElem.attributeValue("id"));
            p.setName(proElem.elementText("name"));
            p.setType(proElem.elementText("type"));
            p.setPrice(proElem.elementText("price"));
            // 3.3 把封装好的Product放入List中
            list.add(p);
        }
        return list;
    }

    /**
     * 根据商品编号查询对应的商品对象
     */
    public Product findById(String id) {
        // 1)读取xml
        Document doc = XMLUtil.getDocument();
        // 2)查询指定id的product标签
        Element proElem = (Element) doc.selectSingleNode("//product[@id='" + id + "']");
        // 3)封装Product对象
        Product p = null;
        if (proElem != null) {
            p = new Product();
            p.setId(proElem.attributeValue("id"));
            p.setName(proElem.elementText("name"));
            p.setType(proElem.elementText("type"));
            p.setPrice(proElem.elementText("price"));
        }
        return p;
    }

    public static void main(String[] args) {
        ProductDao dao = new ProductDao();
        List<Product> list = dao.findAll();
        for (Product product : list) {
            System.out.println(product);
        }
        System.out.println("--------------------------");
        Product p = dao.findById("2");
        System.out.println(p);
    }
}
package day10hist.cn.jxufe.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * 把xml文件的通用的操作方法抽取出来
 * @author APPle
 *
 */
public class XMLUtil {

    /**
     * 读取xml文件,返回document对象
     */
    public static Document getDocument() {
        try {
            Document doc = new SAXReader().read(new File("e:/product.xml"));
            return doc;
        } catch (DocumentException e) {
            e.printStackTrace();
            // 把转换为运行时异常抛出即可!
            throw new RuntimeException(e);
        }
    }

    /**
     * 传如docuemnt对象,写出到xml文件中
     */
    public static void write2xml(Document doc) {
        try {
            OutputStream out = new FileOutputStream("e:/product.xml");
            OutputFormat format = OutputFormat.createPrettyPrint();
            XMLWriter writer = new XMLWriter(out, format);
            writer.write(doc);
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            // 把转换为运行时异常抛出即可!
            throw new RuntimeException(e);
        }
    }
}
package day10hist.cn.jxufe.servlet;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import day10hist.cn.jxufe.dao.ProductDao;
import day10hist.cn.jxufe.entity.Product;

/**
 * 显示商品详情的servlet
 * @author APPle
 *
 */
public class DetailProductServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1)接收id的参数
        String id = request.getParameter("id");
        // 2)查询指定id的商品对象
        ProductDao dao = new ProductDao();
        Product product = dao.findById(id);
        // 3)显示到浏览器上
        response.setContentType("text/html;charset=utf-8");
        String html = "";

        html += "<html>";
        html += "<head><title>查看商品详情</title></head>";
        html += "<body>";
        html += "<table border='1' align='center' width='250px'>";
        html += "<tr><th>编号</th><td>" + product.getId() + "</td></tr>";
        html += "<tr><th>商品名称</th><td>" + product.getName() + "</td></tr>";
        html += "<tr><th>商品型号</th><td>" + product.getType() + "</td></tr>";
        html += "<tr><th>价格</th><td>" + product.getPrice() + "</td></tr>";
        html += "</table>";
        html += "<center><a href='" + request.getContextPath() + "/ListProductServlet'>[返回商品列表]</a></center>";
        html += "</body>";
        html += "</html>";

        response.getWriter().write(html);

        // 4)创建Cookie对象,存放浏览过的商品编号
        Cookie c = new Cookie("prodHist", getCookieValue(request, product.getId()));
        // 5)发送到浏览器保存
        response.addCookie(c);
    }

    /**
     *   规则: 
     *     1)不能超过3个,最多3个
     *     2)最后访问的商品放在最前面
     *     
     * 该方法返回最终生成的浏览过的商品的编号列表
     *         现在的值                                               传入的id值                                 最终的值          算法
     *     null或没有prodHist          1                  1              直接返回传入的id   
     *         2,1                   1                  1,2        小于3个,且id有重复的: 删除重复的id,把传入的id放前面
     *         2,1                   3                  3,2,1 小于3个,且id没有重复的:直接把传入的id放前面
     *         3,2,1                 2                  2,3,1 等于3个,且id有重复的: 删除重复的id,把传入的id放前面
     *         3,2,1                 4                  4,3,2 等于3个,且id没有重复的:    删除结尾的id,把传入的id放前面                     
     *       
     * @return
     */
    private String getCookieValue(HttpServletRequest request, String id) {
        Cookie[] cookies = request.getCookies();
        String prodHist = null;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("prodHist")) {
                    prodHist = cookie.getValue();
                    break;
                }
            }
        }
        if (cookies == null || prodHist == null) {
            // 1)直接返回传入的id
            return id;
        }

        // 3,10 1
        // 满足两个条件:1)方便判断元素是否重复 2)方便增删元素内容 使用集合: Collection coll.contains(id):
        // 判断指定元素是否存在
        // List: ArrayList LinkedList(链表)
        // String-> String[]
        String[] prodHists = prodHist.split("#");
        // String->Collection
        Collection colls = Arrays.asList(prodHists);
        // Collectoin->LinkedList
        LinkedList list = new LinkedList(colls);

        if (list.size() < 3) {
            // 有重复的
            if (list.contains(id)) {
                // 删除重复的id,把传入的id放前面
                list.remove(id);
                list.addFirst(id);
            } else {
                // 直接把传入的id放前面
                list.addFirst(id);
            }
        } else {
            // 有重复的
            if (list.contains(id)) {
                // 删除重复的id,把传入的id放前面
                list.remove(id);
                list.addFirst(id);
            } else {
                // 删除结尾的id,把传入的id放前面
                list.removeLast();
                list.addFirst(id);
            }
        }

        // List->String
        String str = "";
        for (Object obj : list) {
            str += obj + "#"; //用逗号(,)分隔可能会报错
        }
        // 去掉最后的#
        str = str.substring(0, str.length() - 1);
        return str;
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
package day10hist.cn.jxufe.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import day10hist.cn.jxufe.dao.ProductDao;
import day10hist.cn.jxufe.entity.Product;

/**
 * 商品列表的servlet
 * @author APPle
 *
 */
public class ListProductServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1)读取到所有商品列表信息
        ProductDao dao = new ProductDao();
        List<Product> list = dao.findAll();

        // 2)把商品显示到浏览器
        response.setContentType("text/html;charset=utf-8");
        String html = "";

        html += "<html>";
        html += "<head><title>查看商品列表</title></head>";
        html += "<body>";
        html += "<table border='1' align='center' width='600px'>";
        html += "<tr><th>编号</th><th>商品名称</th><th>商品型号</th><th>价格</th><th>查看详情</th></tr>";
        // 2.1 遍历所有的商品,有几个商品有几行数据
        if (list != null) {
            for (Product product : list) {
                html += "<tr>";
                html += "<td>" + product.getId() + "</td>";
                html += "<td>" + product.getName() + "</td>";
                html += "<td>" + product.getType() + "</td>";
                html += "<td>" + product.getPrice() + "</td>";
                // 访问DetailProdServlet同时传递一个名称为id的参数
                html += "<td><a href='" + request.getContextPath() + "/DetailProductServlet?id=" + product.getId()
                        + "'>查看</a></td>";
                html += "</tr>";
            }
        }

        html += "</table>";
        // 3)显示浏览过的商品
        html += "<hr/>";
        html += "最近浏览过的商品:<br/>";
        // 3.1)从cookie取出prodHist
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("prodHist")) {
                    String prodHist = cookie.getValue(); // 包含商品编号 。 3,2,1
                    String[] ids = prodHist.split("#");
                    for (String id : ids) {// 取出每个商品编号
                        // 使用商品编号查询对应的商品
                        Product p = dao.findById(id);
                        // 显示商品信息
                        html += "" + p.getId() + "&nbsp;" + p.getName() + "&nbsp;" + p.getPrice() + "<br/>";
                    }
                    break;
                }
            }
        }

        html += "</body>";
        html += "</html>";

        response.getWriter().write(html);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

3.Session技术

3.1 引入

Cookie特点:

1)会话数据放在浏览器端

2)数据类型只能string,而且有大小限制的

3)相对数据存放不安全。

 Session特点:

1)会话数据放在服务器端(服务器内存),占用服务器资源

2)数据类型任意类型,没有大小限制的。

3)相对安全

3.2 Session使用步骤

HttpSession对象:

1)创建HttpSession对象,用于保存会话数据

session = request.getSession();   创建或获取session对象

2)修改HttpSession对象

void setMaxInactiveInterval(int interval)  设置session对象的有效时间

void invalidate()   手动销毁session对象

3)保存会话数据(作为域对象)

session.setAttribute("name",Object);  保存数据

session.getAttribute("name")   获取数据

session.removeAttribute("name") 删除数据

3.3 Session原理

问题: 服务器怎么区分不同的浏览器会话?

前提:  可以从session对象取出数据必须是存放数据的sessinon对象!!!

1)浏览器1-窗口1(001): 

 //1)创建HttpSession对象

 HttpSession session = request.getSession();  给session对象分配001

//2)保存会话数据

session.setAttribute("name", "jacky");

                  

 2)浏览器1-窗口2(001):

 //1)得到session对象

HttpSession session = request.getSession();   搜索001的session对象

 //2)获取会话数据

String name =  (String)session.getAttribute("name");     可以得到!!

3)浏览器2(没有标记或不是001)

//1)得到session对象

 HttpSession session = request.getSession();

//2)获取会话数据

 String name =  (String)session.getAttribute("name");    不可以得到!

  4)新的浏览器1(没有标记或不是001)

//1)得到session对象

 HttpSession session = request.getSession();

 //2)获取会话数据

String name =  (String)session.getAttribute("name");     不可以得到!!

                                                                

1)服务器创建Session对象,服务器会给这个session对象分配一个唯一的标记JSESSIONID

2)把JSESSIONID作为Cookie发送给浏览器

3)浏览器得到JSESSIONID保存下来,在下次访问时携带这个JSESSIONID去访问服务器

4)服务器得到JSESSIONID,在服务器内存中搜索是否存在指定JSSESSINOID的session对象,

5)如果找到,则返回这个session对象

6)如果找不到,可能直接返回null,或者再创建新的session对象。          

HttpSession session = request.getSession();

结论: 通过JSESSIONID在服务器中查询对应的session对象。

3.4 Session细节                  

1)setMaxInactiveInterval(秒数): 设置session对象的有效时间

问题:session在什么销毁?

注意:不是浏览器关闭,session对象就销毁!!!

默认情况: 等待30分钟空闲时间,session对象才会销毁。

<!-- 设置全局的session对象的过期时间 (分钟)-->
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

     2)可以让JSESSIONID不会随着浏览器关闭而丢失!!!!

        3)直接手动销毁sessino对象

 invalidate();

                                              

4)  创建或得到session对象

request.getSession() / request.getSession(true): 创建或得到session对象,查询session对象,如果没有sessino对象,则       创建新的session对象

request.getSession(false)          得到session对象。 查询session对象,如果session对象,直接返回null

package day10Session.cn.jxufe.b_session;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionDemo1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /**
         * 把数据保存到HttpSession对象中
         */
        // 1)创建HttpSession对象
        HttpSession session = request.getSession(true);

        /*
         * 设置session的有效时间
         */
        // session.setMaxInactiveInterval(20);

        /**
         * 设置JSESSIONID的时间,不会随着浏览器关闭而丢失!
         */
        Cookie c = new Cookie("JSESSIONID", session.getId());
        c.setMaxAge(1 * 30 * 24 * 60 * 60);// 1个月
        response.addCookie(c);

        // 2)保存会话数据
        session.setAttribute("name", "jacky");
    }

}
package day10Session.cn.jxufe.b_session;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionDemo2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /**
         * 从HttpSession对象中获取数据
         */
        // 1)得到session对象
        HttpSession session = request.getSession(false);

        // 2)获取会话数据
        if (session == null) {
            System.out.println("没有session对象");
        } else {
            String name = (String) session.getAttribute("name");
            System.out.println("name=" + name);
        }
    }

}
package day10Session.cn.jxufe.b_session;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionDemo3 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1)得到session对象
        HttpSession session = request.getSession();
        // 2)销毁
        session.invalidate();

        System.out.println("销毁成功");
    }

}

3.5 案例-用户登录

<?xml version="1.0" encoding="utf-8"?>
<user-list>
    <user id="1">
        <name>eric</name>
        <password>123456</password>
    </user>
    <user id="2">
        <name>张三</name>
        <password>123456</password>
    </user>
    <user id="3">
        <name>李四</name>
        <password>123456</password>
    </user>
</user-list>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>登录页面</title>
    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <form action="/day10login/LoginServlet" method="post">
        用户名:<input type="text" name="name"/><br/>
        密码:<input type="password" name="password"/><br/>
        <input type="submit" value="登录"/>    
    </form>
  </body>
</html>
package day10login.cn.jxufe.entity;

/*
 * 用户实体对象
 */
public class User {
    private String id;
    private String name;
    private String password;

    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 getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
    }

}
package day10login.cn.jxufe.dao;

import org.dom4j.Document;
import org.dom4j.Element;

import day10login.cn.jxufe.entity.User;
import day10login.cn.jxufe.util.XMLUtil;

public class UserDao {
    /**
     * 根据用户名查询对应的用户
     */
    public User findByName(String name) {
        // 1)读取xml文件
        Document doc = XMLUtil.getDocument();
        // 2)查询是否存在name的文本内容为指定内容的标签
        Element nameElem = (Element) doc.selectSingleNode("//name[text()='" + name + "']");
        User user = null;
        if (nameElem != null) {
            // 创建User对象
            user = new User();
            // 把user的标签信息封装到User对象
            Element userElem = nameElem.getParent();
            user.setId(userElem.attributeValue("id"));
            user.setName(userElem.elementText("name"));
            user.setPassword(userElem.elementText("password"));
        }
        return user;
    }

    public static void main(String[] args) {
        UserDao dao = new UserDao();
        System.out.println(dao.findByName("张三"));
    }
}
package day10login.cn.jxufe.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * 把xml文件的通用的操作方法抽取出来
 */
public class XMLUtil {

    /**
     * 读取xml文件,返回document对象
     */
    public static Document getDocument() {
        try {
            Document doc = new SAXReader().read(new File("e:/user.xml"));
            return doc;
        } catch (DocumentException e) {
            e.printStackTrace();
            // 把转换为运行时异常抛出即可!
            throw new RuntimeException(e);
        }
    }

    /**
     * 传如docuemnt对象,写出到xml文件中
     */
    public static void write2xml(Document doc) {
        try {
            OutputStream out = new FileOutputStream("e:/user.xml");
            OutputFormat format = OutputFormat.createPrettyPrint();
            XMLWriter writer = new XMLWriter(out, format);
            writer.write(doc);
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            // 把转换为运行时异常抛出即可!
            throw new RuntimeException(e);
        }
    }
}
package day10login.cn.jxufe.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import day10login.cn.jxufe.dao.UserDao;
import day10login.cn.jxufe.entity.User;

/*
 * 处理登录逻辑的servlet
 */
public class LoginServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //解决post提交的参数中文乱码
        request.setCharacterEncoding("utf-8");
        //解码输出数据的中文乱码
        response.setContentType("text/html;charset=utf-8");
        //1)接收参数
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        
        
        //2)到”数据库“查询是否存在该用户
        UserDao dao = new UserDao();
        User user = dao.findByName(name);
        if(user!=null){
            //用户名存在,继续判断是否存在密码
            if(user.getPassword().equals(password)){
                //登录成功
                //跳转到用户主页
                /**
                 * ========================================
                 */
                /**
                 * 把用户数据保存到session对象中
                 */
                HttpSession session = 
                        request.getSession(true);
                session.setAttribute("user", user);
                /**
                 * ========================================
                 */
                
                //使用重定向
                response.sendRedirect(request.getContextPath()+"/UserIndexServlet");
            }else{
                //提示密码错误
                response.getWriter().write("密码输入有误,请重新输入!");
            }
            
        }else{
            //提示用户名不存在
            response.getWriter().write("该用户名不存在!");
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        doGet(request, response);
    }

}
package day10login.cn.jxufe.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LogoutServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        /**
         * 注意:如果把整个session对象注销的话,session对象中的所有数据都不用了!!!
         */
        /**
         * ========================================
         */
        // 清除掉登录使用过的user数据
        // 1)获取session对象
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.removeAttribute("user");

            response.getWriter().write("注销成功!<a href='" + request.getContextPath() + "/login.html'>返回登录页面</a>");
        }
        /**
         * ========================================
         */
    }

}
package day10login.cn.jxufe.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import day10login.cn.jxufe.entity.User;

public class UserIndexServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");

        /**
         * ========================================
         */
        /**
         * 从session对象中取出用户数据
         */
        HttpSession session = request.getSession(false);

        User user = null;
        if (session == null) {
            // 代表没有登录成功过,重新登录
            response.sendRedirect(request.getContextPath() + "/login.html");
            return;
        } else {
            // 判断session中是否保存了名称为user的数据
            user = (User) session.getAttribute("user");
            if (user == null) {
                // 代表没有登录成功过,重新登录
                response.sendRedirect(request.getContextPath() + "/login.html");
                return;
            }
        }
        /**
         * ========================================
         */

        response.getWriter().write(
                "登录成功,欢迎回来," + user.getName() + "。<a href='" + request.getContextPath() + "/LogoutServlet'>【安全退出】</a>");
    }
}

原文地址:https://www.cnblogs.com/xinmomoyan/p/11197829.html