zoukankan      html  css  js  c++  java
  • Servlet Java Web开发4 Cookie 和Session

    Cookie 的概念

    Cookie就是若干组键值对。

    服务器在响应头中以如下格式设置cookie

    l

    浏览器将cookie存储在本地,在以后的访问中,在请求中以如下形式发给服务器

    关键API

    服务器写Cookie

    Cookie c=new Cookie("id", "the id is legion");
    esponse.addCookie(c);
    //多个依次重复

    服务器读cookie

    //从请求头中获取cookie数组
    Cookie[] cs=request.getCookies();
    //对于数组中每一个Cookie,有getName 和getValue的方法
    //分别获取键和值

    例子:本例子AServlet写若干cookie,其中一个cookie有key为”id“,

    BServlet试图读取该id 的值。

    //AServlet Get
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.setContentType("text/html;charset=utf-8");
            Cookie c=new Cookie("id", "the id is legion");
            response.addCookie(c);
            Cookie c2=new Cookie("something", "sskalsa");
            response.addCookie(c2);
            response.getWriter().print("i sent you an id in cookie");
            
        }
    
    //BServlet Get
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.setContentType("text/html;charset=utf-8");
            Cookie[] cs=request.getCookies();
            if(cs!=null) {
                for(Cookie c:cs) {
                    if(c.getName().equals("id")) {
                        String str="获取ID的值为"+c.getValue();
                        response.getWriter().print(str);
                    }
                }
            }
        }
    View Code

     Cookie  查看和寿命

    chrome://settings/content

    使用setMaxAge设置cookie寿命,参数单位为秒。服务器回复格式

    设置为-1,表示cookie只在内存存在。设置为0,表示通知浏览器在本地彻底删除该cookie。

     Cookie路径和语言

    设置:cookie.setPath("/cookietest/servlet");

    如果请求路径包含了该Cookie路径,那么就会在请求中包含该cookie。

    默认路径:如果没有使用setPath,那么cookie 的默认路径算到项目名。

    比如访问http://localhost:8080/HelloWeb/AServlet,设置了cookie但没有设置路径,其路径就是/HelloWeb

    如何使得所有二级域名共享cookies

     cookie.setPath("/");   cookie.setDomain("*.XXX.com");

    cookie语言问题

    使用URLEncoder.encode和URLDecoder.decode

    Sessions

    一个例子:说明:登录页面

    输入用户名后,以post参数的形式(在body中username=XXXX跳转到LoginServlet

    没有登录访问index1.jsp提示“你还没有登录”,如果已经登录,打印出用户名。

    核心API。

    servlet 中使用HttpSession s=request.getSession();

    然后 session.setAttribute("username",name);

    index1.jsp 中使用session.getAttribute("username");

    所有代码

    /////index1.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Index 1 Page</title>
    </head>
    <body>
      <body>
    <h1>index1.jsp</h1>
    <%
        String username = (String)session.getAttribute("username"); 
        if(username == null) {
            out.print("您还没有登录!"); 
        } else {
            out.print("用户名:" + username); 
        }
    %>
    <hr/>
    <a href="/HelloWeb/index2.jsp">index2</a>
      </body>
    
    </body>
    </html>
    
    
    
    
    ////login.jsp
    
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h1>login.jsp</h1>
        <hr/>
        <form action="/HelloWeb/LoginServlet" method="post">
            用户名:<input type="text" name="username" /><br/>
            <input type="submit" value="Submit"/>
        </form>
    
    </body>
    </html>
    
    //////LoginServlet
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.setContentType("text/html;charset=utf-8");
            String name = request.getParameter("username");
            if (name.equalsIgnoreCase("rightuser")) {
                HttpSession session = request.getSession();
                session.setAttribute("username", name);
                response.sendRedirect("/HelloWeb/index1.jsp");
            } else {
                response.getWriter().println("用户名错误");
            }
        }
    View Code

    Cookie 

    浏览器第一次访问服务器,cookie没有JSESSIONID

    服务器返回

    以后每次浏览,request头中都携带

    使用sessions技术实现图形验证码

    响应处理servlet分别打印正确或者错误

    为了简化起见,这里不考虑用户名和密码的问题,只考虑验证码是否正确

    login的代码

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h1>login.jsp</h1>
        <hr/>
        
        <form action="/HelloWeb/LoginServlet" method="post">
            用户名:<input type="text" name="username" /><br/>
            密码:  <input type="password" name="password"/><br/>
            验证码:<input type="text" name="verifyCode" size=3/>
            <img id="img" src="/HelloWeb/BServlet"/>
            <a href="javascript:change()">换一张</a>
            <br/>
            <input type="submit" value="Submit"/>
        </form>
    <script type="text/javascript">
    function change() {
        var img=document.getElementById("img");
        img.src="/HelloWeb/BServlet?a="+new Date().getTime();
        
    }
    </script>
    </body>
    </html>

     这里关键的点:

    <img id="img" src="/HelloWeb/BServlet"/>
    这里BServlet 的代码,BServlet 负责使用VerifyCode类生成随机图形,及其对应的文本。
    这里往session中设置了vc的值,
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            VerifyCode vc=new VerifyCode();
            BufferedImage image=vc.getImage();
            request.getSession().setAttribute("vc", vc.getText());
            VerifyCode.output(image, response.getOutputStream());
        }

    在处理用户请求的LoginServlet中会提取session 中键 vc的值,将其和用户输入的文本进行比较

    下面是LoginServlet的代码

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.setContentType("text/html;charset=utf-8");
            String scode=(String)request.getSession().getAttribute("vc");
            String paramCode=request.getParameter("verifyCode");
            if(!paramCode.equals(scode)) {
                response.getWriter().print("验证码错误");
            }else {
                response.getWriter().println("验证码正确");
            }
            
        }

     辅助类VerifyCode的代码

    package com.legion;
    
    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    
    public class VerifyCode {
        private int w = 70;
        private int h = 35;
         private Random r = new Random();
         // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
        private String[] fontNames  = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"};
        // 可选字符
        private String codes  = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
        // 背景色
        private Color bgColor  = new Color(255, 255, 255);
        // 验证码上的文本
        private String text ;
        
        // 生成随机的颜色
        private Color randomColor () {
            int red = r.nextInt(150);
            int green = r.nextInt(150);
            int blue = r.nextInt(150);
            return new Color(red, green, blue);
        }
        
        // 生成随机的字体
        private Font randomFont () {
            int index = r.nextInt(fontNames.length);
            String fontName = fontNames[index];//生成随机的字体名称
            int style = r.nextInt(4);//生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
            int size = r.nextInt(5) + 24; //生成随机字号, 24 ~ 28
            return new Font(fontName, style, size);
        }
        
        // 画干扰线
        private void drawLine (BufferedImage image) {
            int num  = 3;//一共画3条
            Graphics2D g2 = (Graphics2D)image.getGraphics();
            for(int i = 0; i < num; i++) {//生成两个点的坐标,即4个值
                int x1 = r.nextInt(w);
                int y1 = r.nextInt(h);
                int x2 = r.nextInt(w);
                int y2 = r.nextInt(h); 
                g2.setStroke(new BasicStroke(1.5F)); 
                g2.setColor(Color.BLUE); //干扰线是蓝色
                g2.drawLine(x1, y1, x2, y2);//画线
            }
        }
        
        // 随机生成一个字符
        private char randomChar () {
            int index = r.nextInt(codes.length());
            return codes.charAt(index);
        }
        
        // 创建BufferedImage
        private BufferedImage createImage () {
            BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 
            Graphics2D g2 = (Graphics2D)image.getGraphics(); 
            g2.setColor(this.bgColor);
            g2.fillRect(0, 0, w, h);
             return image;
        }
        
        // 调用这个方法得到验证码
        public BufferedImage getImage () {
            BufferedImage image = createImage();//创建图片缓冲区 
            Graphics2D g2 = (Graphics2D)image.getGraphics();//得到绘制环境
            StringBuilder sb = new StringBuilder();//用来装载生成的验证码文本
            // 向图片中画4个字符
            for(int i = 0; i < 4; i++)  {//循环四次,每次生成一个字符
                String s = randomChar() + "";//随机生成一个字母 
                sb.append(s); //把字母添加到sb中
                float x = i * 1.0F * w / 4; //设置当前字符的x轴坐标
                g2.setFont(randomFont()); //设置随机字体
                g2.setColor(randomColor()); //设置随机颜色
                g2.drawString(s, x, h-5); //画图
            }
            this.text = sb.toString(); //把生成的字符串赋给了this.text
            drawLine(image); //添加干扰线
            return image;        
        }
        
        // 返回验证码图片上的文本
        public String getText () {
            return text;
        }
        
        // 保存图片到指定的输出流
        public static void output (BufferedImage image, OutputStream out) 
                    throws IOException {
            ImageIO.write(image, "JPEG", out);
        }
    }
  • 相关阅读:
    Python基础之列表功能
    python基础之字符串基本功能
    Linux服务器上搭建codis集群之——安装前环境准备
    centos7环境开启WIFI热点
    升级glibc、gcc、zlib等
    修复Nginx 502错误:upstream sent too big header while reading response header from upstream
    PS 命令详解
    Linux下网络文件系统NFS服务搭建易错点总结
    2020美赛建模竞赛一等奖经验心得分享
    团队获奖总结
  • 原文地址:https://www.cnblogs.com/legion/p/9307483.html
Copyright © 2011-2022 走看看