Cookie和Session

Cookie

what

服务器跟踪用户信息的技术称为会话技术。

  • Cookie是一种会话技术,它用于将会话过程中的数据保存到用户的浏览器中,
  • 过程:
  • 当用户通过浏览器web服务器的时候,服务器会给客户端发送一些信息,这些信息会保存在Cookie中,当浏览器再次访问服务器的时候,会在请求头中将Cookie的信息发送到服务器中,
  • 服务器在向客户端发送Cookie的时候,在Http的响应字段添加:set-cookie: user=is; path=/;(属性之间必须添加空格和分号)。
    在这里插入图片描述

cookie API

  • public Cookie(String name,String vlaue) : name一经确定不能更改,value的值可以更改
  • String getName() : 得到Cookie的名称
  • Void setValue(String new Value) : 为Cookie设置一个新值
  • String getValue(): 得到Cookie的值
  • void setMaxAge( int expiry) :cookie在浏览器上到期的时间
  • int getMaxAge() :
  • void setPath(String url): 设置Cookie的有效目录
  • String getPath(): 得到Cookie的有效目录
  • void setDomain(String pattern): 设置Cookie的有效域
  • String getDomain(): 返回该Cookie的有效域
  • void setVersion(int v): 设置cookie的版本
  • int getVersion():
  • void setComment(String purpose) 设置Cookie的注解部分
  • String getComment():
  • void setSecure(boolean flag): 设置时候使用安全的协议传送
public class MyCookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        String  lastAccessTime = null;
        Cookie[] cookies = req.getCookies();
        for(int i = 0;i < cookies.length;i++){
            if("lastAccess".equals(cookies[i].getName())){
                lastAccessTime = cookies[i].getValue();
                break;
            }
        }
        /*=是赋值运算符,==是关系运算符; ===是全等运算符。*/
        if (lastAccessTime ==null){
            resp.getWriter().println("第一次访问该网站");
        } else {
            resp.getWriter().println("您的上次的访问时间是" + lastAccessTime );
        }
        String format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
        Cookie cookie = new Cookie("lastAccess",format);
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

Session

  • 将会话数据保存到服务端的技术
  • 过程
  • 浏览器访问Web服务器的时候,Servlet容器就会创建一个Session对象和ID属性,其中Session对象中保存相关数据,ID相当于标识号,当客户端再次访问浏览器的时候,只要将标识号传递给服务器,服务器就可以根据ID拿到相对的Session对象来给它服务。
  • 其中:ID的传递是靠Cookie传递的。

HttpSessionApi

  • 重载
  • public HttpSession getSession(boolean create)
  • public HttpSession getSession();
  • 方法
  • String getId()
  • long getCreationTime()
  • long getLastAccessedTime()
  • void setMaxinactiveInterval(int interval) 修改当前会话的默认超时时间间隔
  • boolean isNew()
  • void invaliddate()
  • ServletContext getServletContext() 返回当前HttpSession对象代表的Web应用程序对象
  • void setAttribute(String name;Object value)
  • String getAttribute()
  • void removeAttribute(String name)

Session 超时管理

  • 因为Http协议中,Web服务器不能判断客户浏览器是否还在继续访问,所以设置指定时间让他关闭。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>

简单购物

public class Book  implements Serializable {
    //定义程序序列化ID。为了验证版本一致性
    private static final long serialVersionUID = 1L;
    private String id;
    private String name;

    public Book() {
    }

    public Book(String id, String name) {
        this.id = id;
        this.name = name;
    }

    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 class BookDB {
    private static final long serialVersionUID = 1L;
    private static Map<String ,Book> books = new LinkedHashMap<String ,Book>();
    static {
        books.put("1",new Book("1","JAVA"));
        books.put("2",new Book("2","jdbc"));
        books.put("3",new Book("3","spring"));
        books.put("4",new Book("4","spring cloud"));
        books.put("5",new Book("5","spring mvc"));
    }
    public static Collection<Book> getAll(){
        return books.values();
    }
    public static Book getBook(String id){
        return books.get(id);
    }
}

public class ListBookServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html/charset=utf-8");
        PrintWriter writer = resp.getWriter();
        Collection<Book> books = BookDB.getAll();
         writer.println("本站提供的图书有:<br />");
        for (Book book : books) {
            String url = "/chatper05/PurchaseServlet?id=" + book.getId();
            writer.println(book.getName() + "<a href='" + url + "' >点击购买<br />");
        }
    }
}

public class CartServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        // 变量cart引用用户的购物车
        List<Book> cart = null;
        //变量pruFlag标记用户是否购买过该商品
        boolean purFlay = true;
        //获得用户的session
        HttpSession session = req.getSession(false);
        //判断
        if (session ==null ){
            purFlay = false;
        }else {
            //获得用户购物车
           cart = (List<Book>) session.getAttribute("cart");
           //如果购物车为空,则purFlag使flase
           if (cart ==null){
               purFlay = false;
           }
        }
        if(!purFlay){
            writer.println("您还没有购买任何东西");
        }else {
            writer.println("您购买的图书有:");
            double price = 0;
            for (Book book : cart) {
                writer.println(book.getName() +"<br />");
            }
        }
    }
}
  • 如果浏览器对cookie功能进行了禁用,拿不到Sesion对象,就需要使用URL实现Session跟踪
  • encodeURL(String url); 对于超链接中和form表单action中url进行重写
  • encodeRedirectURL(String url): 对传递到sendRedirect()中的URL进行重写
  • 进行重写后session的标识号就会出现在请求地址中

简单登录

package com.login;

public class User {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

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

package com.login;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        PrintWriter writer = resp.getWriter();
        if ("chen".equals(username) && "123".equals(password)){
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            req.getSession().setAttribute("user",user);
            resp.sendRedirect("/chapter05/IndexServlet");
        }else {
            writer.println("用户名和密码错误,登录失败");
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req,resp);
    }
}

package com.login;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class IndexServlet extends HttpServlet {



    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码问题
        PrintWriter respWriter = resp.getWriter();
        resp.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if(user == null){
            respWriter.println("您还没有登录,请<a href='/chapter05/Login.html'>登录</a>'");
        }else {
            respWriter.println("您已登录,欢迎您:" + user.getUsername() +"!");
            respWriter.println("<a href='/chapter05/LogoutServlet'></a>");
            //创建Cookie存储Session的标识号
            Cookie jsessionid = new Cookie("JSESSIONID", session.getId());
            jsessionid.setMaxAge(60 * 30);
            jsessionid.setPath("/chapter05");
            resp.addCookie(jsessionid);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req, resp);
    }
}

package com.login;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        //将Session中User对象移除
        req.getSession().removeAttribute("user");
        resp.sendRedirect("/chapter05/IndexServlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form name="reg" action="/chapter05/LoginServlet" method="post"><br>
    用户名: <input type="text" name="username">
    密码: <input type="password" name="password">
    &nbsp;&nbsp;&nbsp;
    <input type="submit" value="登录" id="bt">
</form>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    <servlet>
        <servlet-name>IndexServlet</servlet-name>
        <servlet-class>com.login.IndexServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>IndexServlet</servlet-name>
        <url-pattern>/IndexServlet</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.login.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/LoginServlet</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>com.login.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/LogoutServlet</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>CheckServlet</servlet-name>
        <servlet-class>com.login.CheckServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CheckServlet</servlet-name>
        <url-pattern>/CheckServlet</url-pattern>
    </servlet-mapping>


</web-app>

复杂登录(加了验证码)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form name="reg" action="/chapter05/LoginServlet" method="post"><br>
    用户名: <input type="text" name="username"><br/>
    密码: <input type="password" name="password"><br/>
    验证码:<input type="text" name="check_code"><br/>
            <img src="/chapter05/CheckServlet">
    &nbsp;&nbsp;&nbsp;<br/>
    <input type="submit" value="登录" id="bt">
</form>
</body>
</html>
package com.login;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class CheckServlet extends HttpServlet {
    private static int WIDTH = 60;//验证码图片宽度
    private static int HEIGHT = 20;//验证码图片高度
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        resp.setContentType("image/jpeg");
        ServletOutputStream sos = resp.getOutputStream();
        //设置浏览器不缓存图片
        resp.setHeader("Pragma","No-cache");
        resp.setHeader("Cache-Control","no-cache");
        resp.setDateHeader("Expires",0);
        //创建内存图像并获得图形上下文
        BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = bufferedImage.getGraphics();
        //产生随机认证码
        char [] rands = generateCheckCode();
        //产生图像
        drawBackground(graphics);
        drawRands(graphics,rands);
        //结束图像的绘制过程,完成图像
        graphics.dispose();
        //将图像输出到客户端
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage,"JPEG",bos);
        byte[] buf = bos.toByteArray();
        resp.setContentLength(buf.length);
        sos.write(buf);
        bos.close();
        sos.close();
        //将当前验证码反倒Session
        session.setAttribute("check_code",new String(rands));
        //下面代码有错,Session对象必须在提交响应前获得
        //req.getSession().setAttribute("check_code",new String(rands));
    }

    private void drawRands(Graphics graphics, char[] rands) {
        graphics.setColor(Color.BLACK);
        graphics.setFont(new Font(null,Font.ITALIC|Font.BOLD,18));
        //在不同的高度输出验证码的每个字符
        graphics.drawString("" + rands[0],1,17);
        graphics.drawString("" + rands[1],16,15);
        graphics.drawString("" + rands[2],31,18);
        graphics.drawString("" + rands[3],46,15);
        System.out.println(rands);

    }

    private void drawBackground(Graphics graphics) {
        //画背景
        graphics.setColor(new Color(0xDCDCDC));
        graphics.fillRect(0,0,WIDTH,HEIGHT);
        //产生120个干扰点
        for(int i=0;i<120;i++){
            int x = (int) (Math.random() * WIDTH);
            int y = (int) (Math.random() * HEIGHT);
            int red = (int) (Math.random() * 255);
            int green = (int) (Math.random() * 255);
            int blue = (int) (Math.random() * 255);
            graphics.setColor(new Color(red,green,blue));
            graphics.drawOval(x,y,1,0);
        }
    }

    //生成一个4字符的验证码
    private char[] generateCheckCode() {
        //定义验证码的字符表
        String chars = "0123456789abcdefghijklmnopqrstuvwxyz";
        char[] rands = new char[4];
        for(int i=0;i<4;i++){
            //返回36之内的所有整数
            int rand = (int) (Math.random() * 36);
            //返回指定索引处的值
            rands[i] = chars.charAt(rand);
        }
        return rands;
    }


}

package com.login;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String check_code = req.getParameter("check_code");
        String code = (String) req.getSession().getAttribute("check_code");
        PrintWriter writer = resp.getWriter();
        if ("chen".equals(username) && "123".equals(password) && check_code.equals(code)){
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            req.getSession().setAttribute("user",user);
            resp.sendRedirect("/chapter05/IndexServlet");
        }else {
            writer.println("用户名和密码错误,登录失败");
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       doGet(req,resp);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值