Java web 2022跟学尚硅谷(十) 后端基础 书城

验证码kaptcha和缓存cookie

简单了解cookie

简单了解cookie

步骤

  1. 创建Cookie对象
  2. 在客户端保存Cookie
  3. 设置Cookie的有效时长
    cookie.setMaxAge(60) , 设置cookie的有效时长是60秒
    cookie.setDomain(pattern);
    cookie.setPath(uri);
  4. Cookie的应用:
    4-1: 记住用户名和密码十天 setMaxAge(60 * 60 * 24 * 10)
    4-2: 十天免登录

简单创建cookie的样例

创建cookie的样例

代码

CookieServlet01
package com.atguigu.cookies;

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

/**
 * @ClassName: CookieServlet01
 * @Description:
 * @Author: wty
 * @Date: 2022/12/14
 */
@WebServlet("/cookie01")
public class CookieServlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        // 1.创建一个cookie对象
        Cookie cookie = new Cookie("uname", "jim");
        // 2.将cookie保存到客户端
        response.addCookie(cookie);

        request.getRequestDispatcher("hello.html").forward(request, response);
    }
}

hello.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Cookie跳转</title>
</head>
<body>
<p1>Cookie成功!</p1>

</body>
</html>

页面结果

页面结果

Cookie保存结果

Cookie保存结果

第二次请求

可以发现请求头和响应头,都有cookie
第二次请求

cookie的API

        // 可以给cookie设置有效时长1800秒,30分钟
        cookie.setMaxAge(1800);

        // 可以给cookie设置路径,当前路径才会带cookie过来
        cookie.setDomain("Path");

Kaptcha验证码

使用步骤

  1. 添加jar包
    添加jar包
  2. 在web.xml文件中注册KaptchaServlet,并设置验证码图片的相关属性
    web.xml文件配置如下:
<?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_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>KaptchaServlet</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
        <init-param>
            <param-name>kaptcha.border.color</param-name>
            <param-value>red</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.char.string</param-name>
            <param-value>abcdefghijklmnopqrstuvw123456789</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.noise.impl</param-name>
            <param-value>com.google.code.kaptcha.impl.NoNoise</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>KaptchaServlet</servlet-name>
        <url-pattern>/kaptcha.jpg</url-pattern>
    </servlet-mapping>
</web-app>
  1. 在html页面上编写一个img标签,然后设置src等于KaptchaServlet对应的url-pattern
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Cookie跳转</title>
    <meta charset="UTF-8">
</head>
<body>
<img src="/kaptcha.jpg"></img>

</body>
</html>

显示效果

验证码

验证码的校验

  1. kaptcha验证码图片的各个属性在常量接口:Constants中
    验证码API

  2. KaptchaServlet在生成验证码图片时,会同时将验证码信息保存到session中。因此,我们在注册请求时,首先将用户文本框中输入的验证码值和session中保存的值进行比较,相等,则进行注册

相关类

KaptchaServlet01
package com.atguigu.cookies;

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

/**
 * @ClassName: KaptchaServlet01
 * @Description:
 * @Author: wty
 * @Date: 2022/12/14
 */
@WebServlet("/kaptcha01")
public class KaptchaServlet01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        Object kaptcha_session_key = session.getAttribute("KAPTCHA_SESSION_KEY");
        System.out.println("kaptcha_session_key =" + kaptcha_session_key);
    }
}

先打开验证码
打开验证码
获取session中的KAPTCHA_SESSION_KEY
获取验证码
查看控制台的输出
查看控制台的输出

书城1.2

正则表达式

正则表达式的使用

正则表达式的使用
1.定义正则表达式的对象
2.定义将校验的字符串
3.校验

 <script type="" language="JavaScript">
        // 或者写成 直接量形式; var reg = /abc/;
        // 对象形式:
        var reg = new RegExp("abc");
        var str = "abdefghi";
        var b = reg.test(str);
        console.log(b);

    </script>
全局匹配(模式匹配)
        // 全局匹配
        var reg2 = /abc/g;
        var str2 = "abctabc"
        str2 = str2.replace(reg2, 'o');
        console.log(str2);

输出

        oto
忽略大小写匹配
        // 忽略大小写
        var reg3 = /a/gi;
        var str3 = "abcAgt";
        str3 = str3.replace(reg3, '_')
        console.log(str3);

输出

_bc_gt
结尾查找

没有加m说明是单行匹配,会认为是一行,则替换最后一个t

        // 结尾查找
        var reg4 = /t$/;
        var str4 = "abcAgt\nabtcgt";
        str4 = str4.replace(reg4, '_')
        console.log(str4);

查找结果

abcAgt
abtcg_
多行查找

这里是多行匹配,所以会看成2行,只替换了最后一行的t

        // 多行查找
        var reg5 = /t$/m;
        var str5 = "abcAgt\nabtcgt";
        str5 = str5.replace(reg5, '_')
        console.log(str5);

结果

abcAg_
abtcgt
元字符
\w

\w:任意数字和字母还有下划线_

        // w:任意数字和字母还有下划线_
        var reg6 = /\w/gim;
        var str6 = "a_>fgeaih*#35";
        str6 = str6.replace(reg6, 'T');
        console.log(str6);

输出

TT>TTTTTT*#TT
\W

和\w正好相反,指非数字和字母还有下划线的所有字符

        // W:非(任意数字和字母还有下划线_)的其它字符
        var reg7 = /\W/gim;
        var str7 = "a_>fgeaih*#35";
        str7 = str7.replace(reg7, 'T');
        console.log(str7);

输出:

a_TfgeaihTT35
.

.是指除了换行符外的任意字符

        // .是指除了换行符外的任意字符
        var reg8 = /./gim;
        var str8 = "a_>.fgeaih*#35";
        str8 = str8.replace(reg8, 'T');
        console.log(str8);

输出

TTTTTTTTTTTTT

如果我们想匹配.只需要加上转义符\即可

        // .想匹配. 需要加转义符\
        var reg9 = /\./gim;
        var str9 = "a_>.fgeaih*#35";
        str9 = str9.replace(reg9, 'T');
        console.log(str9);

结果

a_>.fgeaih*#35
\s和\S

\s是匹配任意的空白符,包括空格、制表符、换页符等等
\S是匹配任意的非空白符,即s取反

        // s 空白符
        var reg10 = /s/;
        var str10 = "\nabad\na cg";
        str10 = str10.replace(reg10, 'T');
        console.log(str10);

输出


abad
a cg
\d和\D

\d表示匹配所有数字
\D表示数字外的其它字符

        // d所有数字
        var reg11 = /\d/igm;
        var str11 = "agwa54sges";
        str11 = str11.replace(reg11, 'T');
        console.log(str11);

输出

agwaTTsges
\b

\b匹配单词的开始或者结束

        // \b匹配单词的开始或者结束
        var reg12 = /\b/igm;
        var str12 = "hello world";
        str12 = str12.replace(reg12, "A");
        console.log(str12);

输出

AhelloA AworldA
^和$

^字符的开始
$字符的结束

        // ^字符的开始
        var reg13 = /^a/igm;
        var str13 = "ahello worldab";
        str13 = str13.replace(reg13, "T");
        console.log(str13);

结果

Thello worldab
        // $字符的结束
        var reg14 = /b$/igm;
        var str14 = "ahello worldab";
        str14 = str14.replace(reg14, "T");
        console.log(str14);

输出结果

ahello worldaT
字符集合
[ ]

表示[ ]中任何一个出现的字符都可以匹配

        // []
        var reg15 = /[ah]/igm;
        var str15 = "ahello worldab";
        str15 = str15.replace(reg15, "T");
        console.log(str15);

结果

TThello worldTb
[^]

[^]取反

        // [^]取反
        var reg16 = /[^ah]/igm;
        var str16 = "ahello worldab";
        str16 = str16.replace(reg16, "T");
        console.log("str16: " + str16);

结果

ahTTTTTTTTTTaT
[-]

[-]表示范围

        // [-]表示范围
        var reg17 = /[a-z]/igm;
        var str17 = "ahello worldab";
        str17 = str17.replace(reg17, "T");
        console.log("str17: " + str17);

结果:

TTTTTT TTTTTTT
|

|表示或者

        // [|]表示或者
        var reg18 = /[a|z]/igm;
        var str18 = "ahelloz worldab";
        str18 = str18.replace(reg18, "T");
        console.log("str18: " + str18);

结果

ThelloT worldTb

出现次数

*出现0次或者多次
+出现1次或者多次
?出现0次或者1次
{n}出现n次或者多次
{n,}出现n次或者多次
{n,m}出现n到m次

        // 出现次数
        var reg19 = /a{2}/igm;
        var str19 = "ahelloz worldaab";
        str19 = str19.replace(reg19, "T");
        console.log("str19: " + str19);

结果

ahelloz worldTb

js中获取html中标签值的方式

function checkRegist() {
    // DOM document
    var elementById = document.getElementById("unameText");
    //BOM方式获取 Browser
    //var uname = document.forms[0].uname;

    return true;
}

注册界面

输入用户信息后给出相关提示

输入用户信息后给出相关提示

用户名失焦后校验是否已经被注册

在这里插入图片描述

相关代码

regist.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>尚硅谷会员注册页面</title>
    <link type="text/css" rel="stylesheet" th:href="@{/static/css/style.css}"/>
    <link rel="stylesheet" th:href="@{/static/css/register.css}"/>
    <style type="text/css">
        .login_form {
            height: 420px;
            margin-top: 25px;
        }
    </style>
    <script language="JavaScript" th:src="@{/static/script/regist.js}"></script>
</head>
<body>
<div id="login_header">
    <a href="../../index.html">
        <img class="logo_img" alt="" th:src="@{/static/img/logo.gif}"/>
    </a>
</div>

<div class="login_banner">
    <div class="register_form">
        <h1>注册尚硅谷会员</h1>
        <form th:action="@{/user.do}" th:method="post" onsubmit="return checkRegist();">
            <input type="hidden" name="operate" value="regist"></input>
            <div class="form-item">
                <div>
                    <label>用户名称:</label>
                    <input id="unameText" type="text" placeholder="请输入用户名" name="uname" value="hsp123"
                           onblur="ckUname(this.value)"/>
                </div>
                <span id="unameSpan" class="errMess">用户名应为6~16位数组和字母组成</span>
            </div>
            <div class="form-item">
                <div>
                    <label>用户密码:</label>
                    <input id="pwdText" type="password" placeholder="请输入密码" name="pwd"/>
                </div>
                <span id="pwdSpan" class="errMess">密码的长度至少为8位</span>
            </div>
            <div class="form-item">
                <div>
                    <label>确认密码:</label>
                    <input id="confirmPwdText" type="password" placeholder="请输入确认密码" name="pwd"/>
                </div>
                <span id="confirmPwdSpan" class="errMess">密码两次输入不一致</span>
            </div>
            <div class="form-item">
                <div>
                    <label>用户邮箱:</label>
                    <input id="emailText" type="text" placeholder="请输入邮箱" name="email"/>
                </div>
                <span id="emailSpan" class="errMess">请输入正确的邮箱格式</span>
            </div>
            <div class="form-item">
                <div>
                    <label>验证码:</label>
                    <div class="verify">
                        <input id="kaptchaText" type="text" name="verifyCode" placeholder=""/>
                        <img th:src="@{/kaptcha.jpg}" alt=""/>
                    </div>
                </div>
                <span id="kaptchaSpan" class="errMess">请输入正确的验证码</span>
                <!--<input id="kaptchaTrueText" type="hidden" th:value="${session.KAPTCHA_SESSION_KEY}">-->
            </div>
            <button class="btn">注册</button>
        </form>
    </div>
</div>
<div id="bottom">
      <span>
        尚硅谷书城.Copyright &copy;2015
      </span>
</div>
</body>
</html>

regist.js异步请求
function checkRegist() {
    // DOM document
    var unameText = $("unameText");
    var uname = unameText.value;

    var unameSpan = $("unameSpan");


    //BOM方式获取 Browser
    //var uname = document.forms[0].uname;
    //用户名不为空,用户名应为6~16位数组和字母组成
    if (null != uname) {
        var unameReg = new RegExp("\\w{6,16}");
        if (unameReg.test(uname)) {
            unameSpan.style.visibility = "hidden";
        } else {
            unameSpan.style.visibility = "visible";
            return false;
        }
    } else {
        unameSpan.style.visibility = "visible";
        return false;
    }

    var pwdText = $("pwdText");
    var pwd = pwdText.value;

    var pwdSpan = $("pwdSpan");
    //密码不为空,密码应为:密码的长度至少为8位
    if (null != pwd) {
        var pwdReg = new RegExp(".{8,}");
        if (pwdReg.test(pwd)) {
            pwdSpan.style.visibility = "hidden";
        } else {
            pwdSpan.style.visibility = "visible";
            return false;
        }
    } else {
        pwdSpan.style.visibility = "visible";
        return false;
    }


    var confirmPwdText = $("confirmPwdText");
    var confirmPwd = confirmPwdText.value;

    var confirmPwdSpan = $("confirmPwdSpan");
    //确认密码不为空,两次密码输入是否一致
    if (null != confirmPwd) {
        if (confirmPwd == pwd) {
            confirmPwdSpan.style.visibility = "hidden";
        } else {
            confirmPwdSpan.style.visibility = "visible";
            return false;
        }
    } else {
        confirmPwdSpan.style.visibility = "visible";
        return false;
    }


    var emailText = $("emailText");
    var email = emailText.value;

    var emailSpan = $("emailSpan");
    //用户邮箱
    if (null != email) {
        var emailReg = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$/;
        if (emailReg.test(email)) {
            emailSpan.style.visibility = "hidden";
        } else {
            emailSpan.style.visibility = "visible";
            return false;
        }
    } else {
        emailSpan.style.visibility = "visible";
        return false;
    }


    var kaptchaText = $("kaptchaText");
    var kaptcha = kaptchaText.value;

    var kaptchaSpan = $("kaptchaSpan");

    // var kaptchaTrueText = $("kaptchaTrueText");
    // var kaptchaTrue = kaptchaTrueText.value;

    // 验证码
    if (null != kaptcha) {
        if (kaptcha.length == 5) {
            kaptchaSpan.style.visibility = "hidden";
        } else {
            kaptchaSpan.style.visibility = "visible";
            return false;
        }
    } else {
        kaptchaSpan.style.visibility = "visible";
        return false;
    }


    return true;
}

function $(id) {
    return document.getElementById(id);
}

var xmlHttpRequest;

// 如果需要发异步请求,我们需要一个关键的对象XMLHttpRequest
function createXMLHttpRequest() {
    // 符合DOM2标准的浏览器创建方式
    if (window.XMLHttpRequest) {
        xmlHttpRequest = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        try {
            xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP")
        } catch (e) {
            xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP")
        }
    }
}

function ckUname(uname) {
    createXMLHttpRequest();
    var url = "user.do?operate=ckUname&uname=" + uname;
    xmlHttpRequest.open("GET", url, true);
    // 设置回调函数
    xmlHttpRequest.onreadystatechange = ckUnameCB;
    // 发送请求
    xmlHttpRequest.send();
}

function ckUnameCB() {
    if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
        // 表示服务器端响应给我的文本内容
        //alert(xmlHttpRequest.responseText);
        var responseText = xmlHttpRequest.responseText;
        // {'uname':'1'}
        //var result = eval(responseText);
        //alert(responseText);
        if (responseText == "{'uname':'1'}") {
            alert("用户名已经被注册");
        } else {
            alert("用户名可以被注册");
        }
    }
}
UserController.java
package com.atguigu.book.controller;

import com.atguigu.book.pojo.Cart;
import com.atguigu.book.pojo.User;
import com.atguigu.book.service.BookService;
import com.atguigu.book.service.CartItemService;
import com.atguigu.book.service.UserService;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @ClassName: UserController
 * @Description:
 * @Author: wty
 * @Date: 2022/12/12
 */

public class UserController {
    private UserService userService;
    private CartItemService cartItemService;

    public String login(String uname, String pwd, HttpSession session) {
        User user = userService.login(uname, pwd);
        System.out.println("user = " + user);

        if (null != user) {
            // 加载购物车的信息
            Cart cart = cartItemService.getCart(user);
            user.setCart(cart);

            // 保存的user是加载了购物车信息的user
            session.setAttribute("currUser", user);
            // 加载价格查询
            session.setAttribute("minPrice", null);
            session.setAttribute("maxPrice", null);

            return "redirect:book.do";
        } else {
            return "user/login";
        }

    }


    public String regist(String uname, String pwd, String email, String verifyCode, HttpSession session, HttpServletResponse response) throws IOException {

        // 获取验证码
        Object kaptcha_session_key = session.getAttribute("KAPTCHA_SESSION_KEY");

        if (null == kaptcha_session_key || !verifyCode.equals((String) kaptcha_session_key)) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            //out.println("<script language = 'javascript'>'alert('验证码不正确!');window.location.href='page.do?operate=page&page=user/regist';</script>");
            out.println("<script language='javascript'>alert('验证码不正确!');</script>");
            return "user/regist";
        } else {
            if (verifyCode.equals((String) kaptcha_session_key)) {
                userService.registe(new User(uname, pwd, email, 0));
                return "user/login";
            }
        }

        return "user/login";

    }

    public String ckUname(String uname) {
        User user = userService.getUser(uname);
        if (null != user) {
            // 表示用户名已经被占用。不能注册
            return "json:{'uname':'1'}";
            //return "ajax:1";
        } else {
            // 用户名未查询到,可以注册
            return "json:{'uname':'0'}";
            //return "ajax:0";
        }
    }
}

DispatcherServlet.java

中央控制器增加逻辑
中央控制器增加逻辑

else if(methodReturnStr.startsWith("json:")){
                        String jsonStr = methodReturnStr.substring("json:".length());
                        PrintWriter out = response.getWriter();
                        out.print(jsonStr);
                        out.flush();
                    }

总结

今日内容:

  1. 注册页面表单验证
    (1) 有一个事件 onsubmit ,
    οnsubmit=“return false” , 那么表单点击提交按钮时不会提交
    οnsubmit=“return true” , 那么表单点击提交按钮时会提交

(2) 获取文档中某一个节点的方式:

//DOM:Document
//var unameTxt = document.getElementById("unameTxt");
//BOM:Browser
//document.forms[0].uname
  1. 原生的Ajax(了解)
    第一步: 客户端发送异步请求;并绑定对结果处理的回调函数
    (1) html相关代码:
 <input type="text" name="uname" onblur="ckUname()"/>

(2) 定义ckUname方法:
- 创建XMLHttpRequest对象
- XMLHttpRequest对象操作步骤:
- open(url,“GET”,true)
- onreadyStateChange 设置回调
- send() 发送请求
- 在回调函数中需要判断XMLHttpRequest对象的状态:
readyState(0-4) , status(200)
0: (Uninitialized) the send( ) method has not yet been invoked.
1: (Loading) the send( ) method has been invoked, request in progress.
2: (Loaded) the send( ) method has completed, entire response received.
3: (Interactive) the response is being parsed.
4: (Completed) the response has been parsed, is ready for harvesting.

0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了

第二步:服务器端做校验,然后将校验结果响应给客户端

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

心向阳光的天域

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

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

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

打赏作者

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

抵扣说明:

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

余额充值