Java web 2022跟学尚硅谷十 后端基础 书城
- 验证码kaptcha和缓存cookie
- 简单了解cookie
- 步骤
- 简单创建cookie的样例
- 代码
- CookieServlet01
- hello.html
- 页面结果
- Cookie保存结果
- 第二次请求
- cookie的API
- Kaptcha验证码
- 使用步骤
- 显示效果
- 验证码的校验
- 相关类
- KaptchaServlet01
- 书城1.2
- 正则表达式
- 正则表达式的使用
- 全局匹配(模式匹配)
- 忽略大小写匹配
- 结尾查找
- 多行查找
- 元字符
- \w
- \W
- .
- \s和\S
- \d和\D
- \b
- ^和$
- 字符集合
- [ ]
- [^]
- [-]
- |
- 出现次数
- js中获取html中标签值的方式
- 注册界面
- 输入用户信息后给出相关提示
- 用户名失焦后校验是否已经被注册
- 相关代码
- regist.html
- regist.js异步请求
- UserController.java
- DispatcherServlet.java
- 总结
验证码kaptcha和缓存cookie
简单了解cookie
步骤
- 创建Cookie对象
- 在客户端保存Cookie
- 设置Cookie的有效时长
cookie.setMaxAge(60) , 设置cookie的有效时长是60秒
cookie.setDomain(pattern);
cookie.setPath(uri); - Cookie的应用:
4-1: 记住用户名和密码十天 setMaxAge(60 * 60 * 24 * 10)
4-2: 十天免登录
简单创建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的API
// 可以给cookie设置有效时长1800秒,30分钟
cookie.setMaxAge(1800);
// 可以给cookie设置路径,当前路径才会带cookie过来
cookie.setDomain("Path");
Kaptcha验证码
使用步骤
- 添加jar包
- 在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>
- 在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>
显示效果
验证码的校验
-
kaptcha验证码图片的各个属性在常量接口:Constants中
-
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 ©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) 有一个事件 onsubmit ,
οnsubmit=“return false” , 那么表单点击提交按钮时不会提交
οnsubmit=“return true” , 那么表单点击提交按钮时会提交
(2) 获取文档中某一个节点的方式:
//DOM:Document
//var unameTxt = document.getElementById("unameTxt");
//BOM:Browser
//document.forms[0].uname
- 原生的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 - (完成)响应内容解析完成,可以在客户端调用了
第二步:服务器端做校验,然后将校验结果响应给客户端