大数据正式18

大数据正式18

验证码校验

1. regist.jsp中提交的有验证码信息
2. RegistServlet中,验证用户提交的信息和验证码生成时的信息是否一致,并进行相应的处理
  • 验证流程
  • EasyMall代码改造

    • ValiImageServlet【把验证码的数据存储到session中】

      package com.easymall.ser;
      
      import java.awt.Color;
      import java.awt.Font;
      import java.awt.Graphics2D;
      import java.awt.image.BufferedImage;
      import java.io.IOException;
      import java.util.Random;
      
      import javax.imageio.ImageIO;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      @SuppressWarnings("serial")
      public class ValiImageServlet extends HttpServlet {
          // 背景参数
          private int base = 30;
          private int height = base;
          private int width = base * 4;
      
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                  throws ServletException, IOException {
              // 禁止浏览器缓存图片
              resp.setHeader("Cache-Control", "no-cache");
              resp.setHeader("Progma", "no-cache");
              resp.setDateHeader("Expires", 0);
              // 创建内存中的图片
              BufferedImage di = new BufferedImage(width, height,
                      BufferedImage.TYPE_INT_RGB);
              // 获取画布画背景
              Graphics2D g2 = (Graphics2D) di.getGraphics();
              // 填充矩形
              g2.setColor(Color.white);
              g2.fillRect(0, 0, width, height);
              // 绘制边框
              g2.setColor(Color.red);
              g2.drawRect(0, 0, width - 1, height - 1);
              // 写字并保存到session
              String valistr2 = "";
              g2.setFont(new Font("微软雅黑", Font.BOLD, 25));
              for (int i = 0; i < 4; i++) {
                  String s = Integer.toString(getRandom(0, 10));
                  valistr2 += s;
                  g2.setColor(new Color(getRandom(0, 255), getRandom(0, 255),
                          getRandom(0, 255)));
                  int temp = getRandom(-45, 45);
                  g2.rotate(temp / 180.0 * Math.PI, 10 + 30 * i, 20);
                  g2.drawString(s, 10 + 30 * i, 20);
                  g2.rotate(-temp / 180.0 * Math.PI, 10 + 30 * i, 20);
              }
              System.out.println("当前验证码:" + valistr2);
              req.getSession().setAttribute("valistr2", valistr2);
              // 画干扰线
              for (int i = 0; i < 3; i++) {
                  g2.setColor(new Color(getRandom(0, 255), getRandom(0, 255),
                          getRandom(0, 255)));
                  g2.drawLine(getRandom(0, width), getRandom(0, height),
                          getRandom(0, width), getRandom(0, height));
              }
              // 画干扰点
              for (int i = 0; i < 5; i++) {
                  g2.setColor(new Color(getRandom(0, 255), getRandom(0, 255),
                          getRandom(0, 255)));
                  g2.drawOval(getRandom(0, width), getRandom(0, height), 5, 5);
              }
              // 画出图片
              ImageIO.write(di, "JPG", resp.getOutputStream());
              // 关闭画布
              g2.dispose();
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                  throws ServletException, IOException {
              this.doGet(req, resp);
          }
      
          // 获取随机数
          private int getRandom(int start, int end) {
              Random random = new Random();
              return start + random.nextInt(end - start);
          }
      
      }
      
    • RegistServlet【注册逻辑中添加两个验证码数据的校验过程】

      package com.easymall.ser;
      
      import java.io.IOException;
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      
      import javax.servlet.ServletContext;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      import com.easymall.exception.MsgException;
      import com.easymall.utils.MySqlUtils;
      
      @SuppressWarnings("serial")
      public class RegisteSer extends HttpServlet {
          private Connection conn = null;
          private PreparedStatement stat = null;
          private ResultSet rs = null;
      
          public void doGet(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              // 全局变量
              try {
                  // 0.获取应用参数
                  ServletContext sc = this.getServletContext();
                  String encode = sc.getInitParameter("encode");
      
                  // 1.解决requestpost请求乱码 解决response输出数据乱码
                  request.setCharacterEncoding(encode);
                  response.setCharacterEncoding(encode);
                  response.setContentType("text/html;charset=" + encode);
      
                  // 2.获取请求参数
                  String username = request.getParameter("username");
                  String password = request.getParameter("password");
                  String password2 = request.getParameter("password2");
                  String nickname = request.getParameter("nickname");
                  String email = request.getParameter("email");
                  String valistr = request.getParameter("valistr");
      
                  // 验证码校验--获取请求参数的验证码,获取session中的验证码,对比并进行相应的操作
                  String valistr2 = (String) request.getSession().getAttribute(
                          "valistr2");
                  if (valistr == null || valistr2 == null
                          || !valistr.equals(valistr2)) {
                      request.setAttribute("msg", "验证码不正确!");
                      request.getRequestDispatcher(
                              request.getContextPath() + "/regist.jsp").forward(
                              request, response);
                      return;
                  }
                  // 3.检查数据有效性 如果有问题 向浏览器报错
                  if (username == null || "".equals(username)) {
                      throw new MsgException("用户名不能为空!");
                  }
      
                  if (password == null || "".equals(password)) {
                      throw new MsgException("密码不能为空!");
                  }
      
                  if (password2 == null || "".equals(password2)) {
                      throw new MsgException("确认密码不能为空!");
                  }
      
                  if (!password.equals(password2)) {
                      throw new MsgException("两次密码不一致!");
                  }
      
                  if (nickname == null || "".equals(nickname)) {
                      throw new MsgException("昵称不能为空!");
                  }
      
                  if (email == null || "".equals(email)) {
                      throw new MsgException("邮箱不能为空!");
                  }
      
                  if (!email.matches("^\\w+@\\w+(\\.\\w+)+$")) {
                      throw new MsgException("邮箱格式不正确!");
                  }
      
                  if (valistr == null || "".equals(valistr)) {
                      throw new MsgException("验证码不能为空!");
                  }
      
                  // 4.存入数据库
                  // 判断账号是否重复
                  conn = MySqlUtils.getConn();
                  stat = conn.prepareStatement("select * from user where username=?");
                  stat.setString(1, username);
                  rs = stat.executeQuery();
      
                  if (rs.next()) {// 账号重复
                      throw new MsgException("账号重复");
                  } else {// 账号不重复
                      stat = conn
                              .prepareStatement("insert into user values(?,?,?,?)");// 账号,密码,昵称,邮箱
                      stat.setString(1, username);
                      stat.setString(2, password);
                      stat.setString(3, nickname);
                      stat.setString(4, email);
                      stat.executeUpdate();
      
                  }
      
                  // 5.向浏览器报告成功 回到主页
                  response.getWriter().write("注册成功!正在前往主页------>>>");
                  response.setHeader("refresh", "1;url=" + request.getContextPath()
                          + "/index.jsp");
              } catch (MsgException e) {
                  String msg = e.getMessage();
                  response.getWriter().write(msg);
                  response.setHeader("refresh", "1;url=/regist.jsp");
              } catch (Exception e) {
                  e.printStackTrace();
                  throw new RuntimeException(e);
              } finally {
                  // 关闭数据库
                  MySqlUtils.close(conn, stat, rs);
              }
      
          }
      
          public void doPost(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException {
              doGet(request, response);
          }
      
      }
      

数据回显

  • 原理:一次请求,一次响应的Request域对象没有被销毁,也没有被改变
  • 流程
    1. 浏览器注册请求【携带一些错误的注册信息存进req域】
    2. 服务器进行校验,发现错误,携带需要回显的数据回到注册界面
    3. 通过Request域获取需要回显的数据进行显示【此时还是属于注册的一次请求一次响应当中】
  • 流程图
  • 代码改造

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML>
    <html>
    <head>
    <title>欢迎注册EasyMall</title>
    <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" href="css/regist.css" />
    <script type="text/javascript" src="js/jquery-1.4.2.js"></script>
    <script type="text/javascript">
        $(document).ready(
                function() {
                    var canSubmit = true;//提交的标志
                    //用户名已存在检查(ajax)    
                    $("input[name='username']").blur(
                            function() {
                                if ($("input[name='username']").val() != "") {
                                    $.get("/UserNameHasServlet?"
                                            + $.param({
                                                "username" : $(
                                                        "input[name='username']")
                                                        .val()
                                            }), function(data) {
                                        if ($.parseJSON(data).hasUser) {
                                            //提示该账户已有
                                            $("input[name='username']")
                                                    .next("span").text("用户名重复!");
                                            canSubmit = false;
                                        } else {
                                            $("input[name='username']")
                                                    .next("span").text("");
                                            canSubmit = true;
                                        }
                                    });
                                }
                            });
    
                    //两次密码的一致性检验(失去焦点)
                    $("input[name='password2']").blur(
                            function() {
                                if ($("input[name='password2']").val() != "") {
                                    if ($("input[name='password']").val() != $(
                                            "input[name='password2']").val()) {//密码不一致
                                        $("input[name='password2']").next("span")
                                                .text("密码不一致!");
                                        canSubmit = false;
                                    } else {
                                        $("input[name='password2']").next("span")
                                                .text("");
                                        canSubmit = true;
                                    }
                                }
                            });
                    //检查邮箱的格式是否正确
                    $("input[name='email']").blur(function() {
                        var email_Reg = /^\w+@\w+(\.\w+)+$/;
                        if ($(this).val() != "" && email_Reg.test($(this).val())) {
                            $(this).next("span").text("");
    
                            canSubmit = true;
                        } else {
                            $(this).next("span").text("邮箱格式不正确!");
                            canSubmit = false;
                        }
                    });
                    //验证码切换(点击事件)
                    $("#yzm_img").click(
                            function() {
                                $(this).attr(
                                        "src",
                                        "/ValiImageServlet?time="
                                                + new Date().getTime());
                            });
                    //表单提交事件
                    $("form").submit(function() {
                        //判断所有的输入框是否为空
                        $.each($("input[type!='submit']"), function() {
                            if ($(this).val() == "") {//密码不一致
                                $(this).nextAll("span").text("数据不能为空!");
                                canSubmit = false;
                            } else {
                                $(this).nextAll("span").text("");
                                canSubmit = true;
                            }
                        });
                        return canSubmit;
                    });
                });
    </script>
    </head>
    <body>
        <h1>欢迎注册EasyMall</h1>
        <form action="/RegisteSer" method="POST" onsubmit="">
            <table>
                <tr>
                    <td class="tds">用户名:</td>
                    <td><input type="text" name="username"
                        value="<%=request.getParameter("username") == null ? "" : request
                        .getParameter("username")%>"><span></span>
                    </td>
                </tr>
                <tr>
                    <td class="tds">密码:</td>
                    <td><input type="password" name="password"><span></span>
                    </td>
                </tr>
                <tr>
                    <td class="tds">确认密码:</td>
                    <td><input type="password" name="password2"><span></span>
                    </td>
                </tr>
                <tr>
                    <td class="tds">昵称:</td>
                    <td><input type="text" name="nickname"
                        value="<%=request.getParameter("nickname") == null ? "" : request
                        .getParameter("nickname")%>"><span></span>
                    </td>
                </tr>
                <tr>
                    <td class="tds">邮箱:</td>
                    <td><input type="text" name="email"
                        value="<%=request.getParameter("email") == null ? "" : request
                        .getParameter("email")%>"><span></span>
                    </td>
                </tr>
                <tr>
                    <td class="tds">验证码:</td>
                    <td><input type="text" name="valistr"><img id="yzm_img"
                        src="/ValiImageServlet" style="cursor: pointer" /><span><font
                            color="#ff0000"><%=request.getAttribute("msg") == null ? "" : request
                        .getAttribute("msg")%></font> </span>
                    </td>
                </tr>
                <tr>
                    <td colspan="2"><input type="submit" value="注册用户" /></td>
                </tr>
            </table>
        </form>
    </body>
    </html>
    

session的工作原理

  • 重要的session的id号Jsessionid【cookie的键,值为浏览器访问的id值】
  • 服务器通过cookie来保存Jsessionid并作为响应头发送给浏览器存入,下次浏览器再次访问服务器数时,通过Jseeionid找服务器中对应的区域,如果找到则用里面的数据
  • 流程图

Cookie被禁用后--URL重写技术解决

  • 原理:将Jsessionid拼接在url后面
  • 如果禁用Cookie,浏览器就不再基于cookie来保存Jsessionid,在服务器中没有这个Jsessionid则找不到对应的Session
  • 解决这个问题,想办法携带Jsessionid来传给服务器---Url重写
    1. resp.encodeURL(String url)【普通的用这个】
    2. resp.RedirectUrl(String url)【重定向用这个】
  • 使用的优缺点
    • 缺点:所有的地址都要这个改变
    • 优点:即使浏览器禁用Cookie,用户也可以正常访问
  • 一般不进行url重写,因为这个错在用户禁用,可以警示用户,也可以引导用户打开浏览器的Cookie

Cookie和Session的区别

  Cookie Session
保存时间: 自行设置 默认30分钟
位置: 客户端保存数据 服务端保存数据
影响: 有可能随着用户的操作被删除 只要不刻意删除对应的数据,在存活期间可以可靠的访问
安全性: 不安全,可以翻看记录来获得相关的信息 安全,数据保存在服务器端
用途: 记住用户名 一次会话的信息:验证码

Cookie和Session的使用

  • 数据长时间保存:cookie
  • 安全性的选择:Session

继续JSP的学习

  • Jsp的指令
    • 格式:<%@ 指令名 若干属性 %>
    • 概述:不产生任何直接的输出,是用来控制jsp解析引擎,如何解析页面中的其他部分内容的
    • 指令
      1. page
        1. 功能:声明当前jsp的基本属性,指挥解析引擎如何翻译jsp页面中的其他部分内容
        2. 属性:
          1. extends:继承哪个类
          2. language:当前jsp使用的开发语言
          3. import:导包【自动导入的包:lang,javax.servlet.,javax.jsp.
          4. session:会话对象【禁止自动生成的sesion="false",默认为true】
          5. buffer
          6. autoFlush
          7. errorPage:错误页面
          8. isErrorPage:是否是错误页面【true/false】【会多一个Exception对象】
          9. contentTpye:
          10. pageEncoding:
          11. isELIgnored:是否支持EL表达式
      2. include
        1. 格式<%@ include file=""%>
        2. 功能:实现页面包含

          <html>
              ...
                  <html>
                      ...
                      ...
                  </html>                 
              ...
          </html>
          
      3. taglib:引入标签库
    • 补充1:乱码
      1. jsp读取翻译的编码:pageEncoding="编码"【保存文件编码和页面编码一致】
      2. 翻译过来的servlet将数据通过Response发送给浏览器【response.setCharacterEncoding("utf-8")】【response.contentType("text/html;charset;utf-8")】这两个相当于:【contentType="text/html;charset=utf-8"】
      3. 上面的两个乱码可以合成一个:pageEncoding="编码"
        1. 文件保存编码
        2. jsp翻译编码
        3. 服务器发送编码
        4. 浏览器解析编码
    • 补充2:错误页面
      • errorPage属性可以配置错误页面,但是太麻烦了给所有的jsp页面
      • 可以在web.xml中配置全局的错误界面

        <error-page>
            <exception-type></exception>
            <location></location>
        </error-page>
        

        <error-page>
            <error-code></error-code>
            <location></location>
        </error-page>
        
      • 配置过全局的错误界面,也配置了具体的,执行具体的

jsp的九大隐式对象【内置的,隐藏的】

  • jsp直接创建的,可以直接拿来用的
    1. application(ServletContext当前web应用)
    2. config(当前Servlet的配置信息)
    3. out(response.getWriter)
    4. session(会话技术HttpSession)
    5. exception(Exception,如果将isError设置为true,则exception代表前一个错误页面的错误信息)
    6. page(代表Servlet)
    7. pageContext(代表当前页面)

      1. 代表当前jsp页面
      2. 作为入口参数获取其他八大隐式对象
      3. 是一个域对象【request,ServletContext,session,pageContext】
          1. 生命周期:访问jsp开始,访问完后销毁
          2. 作用范围:当前jsp页面
          3. 主要功能:
              1. 在当前jsp中共享数据
                  1. setAttribute(String,Objejct)
                  2. getAttribute(String)
                  3. removeAttribute(String)
              2. 作为入口对象操作四大作用域对象
                  1. setAttribute(String name,Objejct obj,int scope)
                  2. getAttribute(String,int scope)
                  3. removeAttribute(String,int scope)
                  4. 对应的域
                      1. PageContext.APPLICATION_SCOPE
                      2. PageContext.SESSION_SCOPE
                      3. PageContext.REQUEST_SCOPE
                      4. PageContext.PAGE_SCOPE
              3. findAttribute(String)
                  1. 寻找指定的对象
                  2. 搜寻的顺序【由小到大:pageContext、Request、session、application】
                  3. 找到返回,找不到返回null
              4. 转发pageContext.forward("路径");
              5. 包含pageContext.include("路径");
      
    8. request(请求)
    9. response(响应)
  • 记忆方法:【page,request,response,config,application,session,Exception,out,pageContext】
  • 对应所学:【Servlet,请求,响应,配置,web应用,会话,异常,输出,页面】

补充之jsp、Session、Cookie

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乘风御浪云帆之上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值