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() + " " + p.getName() + " " + 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>"); } }