大数据正式18

来源:互联网 发布:淘宝销售类目排行榜 编辑:程序博客网 时间:2024/06/14 10:04

大数据正式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的区别

 CookieSession保存时间:自行设置默认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