书城项目第六阶段
- 页面样式
- 1、导入谷歌验证码的jar包
- 2、在web.xml中去配置用于生成验证码的Servlet程序
- 3、在表单中使用img标签去显示验证码图片并使用它
- 4、在服务器获取谷歌生成的验证码和客户端发送过来的验证码比较使用。
3、项目第六阶段
页面样式
登录成功
登录之后的首页
3.1、登录——显示用户名
修改 UserServlet
package com.atguigu.web;
import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import com.atguigu.service.impl.UserServiceImpl;
import com.atguigu.utils.WebUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UserServlet extends BaseServlet {
private UserService userService = new UserServiceImpl();
/**
* 处理登录的功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
//2、调用XxxService.xxx()处理业务
User loginUser = userService.login(new User(null, username, password, null));
//如果等于null,说明登录失败
if (loginUser==null){
// 把错误信息,和回显的表单项信息,保存到Request域中
req.setAttribute("msg","用户名或密码错误!");
req.setAttribute("username",username);
// 跳回登录页面
req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);
}else {
// 成功
//保存用户登录的信息
req.getSession().setAttribute("user",loginUser);
// 跳到成功页面login_success.jsp
req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp);
}
}
/**
* 处理注册的功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
String code = req.getParameter("code");
// Map<String, String[]> parameterMap = req.getParameterMap();
// for (Map.Entry<String, String[]> entry:parameterMap.entrySet()) {
// System.out.println(entry.getKey()+"="+ Arrays.asList(entry.getValue()));
// }
// User user=new User();
// WebUtils.copyParamToBean(req,user);//注入赋值,与User类中setXxx对应
User user = WebUtils.copyParamToBean(req.getParameterMap(),new User());//注入赋值,与User类中setXxx对应
// 2、检查验证码是否正确 ===写死,要求验证码为:abcde
if ("abcde".equalsIgnoreCase(code)){
// 3、检查用户名是否可用
if (userService.existUsername(username)){
System.out.println("用户名["+username+"]已存在!");
// 把回显信息保存到Request域中
req.setAttribute("msg","用户名已存在!!");
req.setAttribute("username",username);
req.setAttribute("email",email);
// 跳回注册页面
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}else {
// 可用 调用Service保存到数据库
userService.registUser(new User(null,username,password,email));
// 跳到注册成功束面regist_success.jsp
req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp);
}
}else {
// 把回显信息保存到Request域中
req.setAttribute("msg","验证码错误!!");
req.setAttribute("username",username);
req.setAttribute("email",email);
System.out.println("验证码["+code+"]错误,");
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}
}
}
修改 login_sucess_menu.jsp
<%--
Created by IntelliJ IDEA.
User: lenovo
Date: 2021/8/21
Time: 下午 03:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div>
<span>欢迎<span class="um_span">${sessionScope.user.username}</span>光临尚硅谷书城</span>
<a href="pages/order/order.jsp">我的订单</a>
<a href="index.jsp">注销</a>
<a href="index.jsp">返回</a>
</div>
修改 index.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>书城首页</title>
<%--静态包含 base标签,css样式,jquery文件 --%>
<%@ include file="/pages/common/head.jsp"%>
</head>
<body>
<div id="header">
<img class="logo_ing" alt="" src="static/img/logo.gif">
<span class= "wel_word">网上书城</span>
<div>
<%-- 如果用户还没有登录,显示【登录和注册的菜单】--%>
<c:if test="${empty sessionScope.user}">
<a href="pages/user/login.jsp">登录</a>
<a href="pages/user/regist.jsp">注册</a>
</c:if>
<%-- 如果已经登录,显示登录之后的用户信息--%>
<c:if test="${not empty sessionScope.user}">
<span>欢迎<span class="um_span">${sessionScope.user.username}</span>光临尚硅谷书城</span>
<a href="pages/order/order.jsp">我的订单</a>
<a href="index.jsp">注销</a>
</c:if>
<a href="pages/cart/cart.jsp">购物车</a>
<a href="pages/manager/manager.jsp">后台管理</a>
</div>
<div id="main">
<div id="book">
<div class="book_cond">
<form action="client/bookServlet" method="get">
<input type="hidden" name="action" value="pageByPrice">
价格:<input id="min" type="text" name="min" value="${param.min}">元 -
<input id="max" type="text" name="max" value="${param.max}">元
<input type="submit" value="查询"/>
</form>
</div>
<div style="...">
<span>您的购物车中有3件商品</span>
<div>
您刚刚将<span style="...">时间简史</span>加入到了购物车中
</div>
</div>
<div>
<c:forEach items="${requestScope.page.items}" var="book">
<div class="b_list">
<div class="img_div">
<img class="book_img" alt="${book.imgPath}"/>
</div>
<div class="book_info">
<div class="book_name">
<span class="sp1">书名:</span>
<span class="sp2">${book.name}</span>
</div>
<div class="book_author">
<span class="sp1">作者:</span>
<span class="sp2">${book.author}</span>
</div>
<div class= "book_price">
<span class="sp1">价格:</span>
<span class="sp2">¥${book.price}</span>
</div>
<div class="book_sales">
<span class="sp1">销量:</span>
<span class="sp2">${book.sales}</span>
</div>
<div class="book_amount">
<span class="sp1">库存:</span>
<span class="sp2">${book.stock}</span>
</div>
<div class="book_add">
<button>加入购物车:</button>
</div>
</div>
</div>
</c:forEach>
</div>
</div>
<%-- 静态包含分页条 --%>
<%@include file="/pages/common/page_nav.jsp"%>
</div>
</div>
<%--静态包含页脚内容--%>
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>
3.2、登出——注销用户
1、销毁Session中用户登录的信息(或者销毁Session)
2、重定向到首页(或登录页面)。
修改 UserServlet
package com.atguigu.web;
import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import com.atguigu.service.impl.UserServiceImpl;
import com.atguigu.utils.WebUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UserServlet extends BaseServlet {
private UserService userService = new UserServiceImpl();
/**
* 登出(注销)
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void logout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、销毁Session中用户登录的信息(或者销毁Session)
req.getSession().invalidate();
// 2、重定向到首页(或登录页面)。
resp.sendRedirect(req.getContextPath());
}
/**
* 处理登录的功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
//2、调用XxxService.xxx()处理业务
User loginUser = userService.login(new User(null, username, password, null));
//如果等于null,说明登录失败
if (loginUser==null){
// 把错误信息,和回显的表单项信息,保存到Request域中
req.setAttribute("msg","用户名或密码错误!");
req.setAttribute("username",username);
// 跳回登录页面
req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);
}else {
// 成功
//保存用户登录的信息
req.getSession().setAttribute("user",loginUser);
// 跳到成功页面login_success.jsp
req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp);
}
}
/**
* 处理注册的功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
String code = req.getParameter("code");
// Map<String, String[]> parameterMap = req.getParameterMap();
// for (Map.Entry<String, String[]> entry:parameterMap.entrySet()) {
// System.out.println(entry.getKey()+"="+ Arrays.asList(entry.getValue()));
// }
// User user=new User();
// WebUtils.copyParamToBean(req,user);//注入赋值,与User类中setXxx对应
User user = WebUtils.copyParamToBean(req.getParameterMap(),new User());//注入赋值,与User类中setXxx对应
// 2、检查验证码是否正确 ===写死,要求验证码为:abcde
if ("abcde".equalsIgnoreCase(code)){
// 3、检查用户名是否可用
if (userService.existUsername(username)){
System.out.println("用户名["+username+"]已存在!");
// 把回显信息保存到Request域中
req.setAttribute("msg","用户名已存在!!");
req.setAttribute("username",username);
req.setAttribute("email",email);
// 跳回注册页面
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}else {
// 可用 调用Service保存到数据库
userService.registUser(new User(null,username,password,email));
// 跳到注册成功束面regist_success.jsp
req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp);
}
}else {
// 把回显信息保存到Request域中
req.setAttribute("msg","验证码错误!!");
req.setAttribute("username",username);
req.setAttribute("email",email);
System.out.println("验证码["+code+"]错误,");
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}
}
}
修改 login_sucess_menu.jsp
<%--
Created by IntelliJ IDEA.: lenovo
Date: 2021/8/21
Time: 下午 03:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div>
<span>欢迎<span class="um_span">${sessionScope.user.username}</span>光临尚硅谷书城</span>
<a href="pages/order/order.jsp">我的订单</a>
<a href="userServlet?action=logout">注销</a>
<a href="index.jsp">返回</a>
</div>
修改 index.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>书城首页</title>
<%--静态包含 base标签,css样式,jquery文件 --%>
<%@ include file="/pages/common/head.jsp"%>
</head>
<body>
<div id="header">
<img class="logo_ing" alt="" src="static/img/logo.gif">
<span class= "wel_word">网上书城</span>
<div>
<%-- 如果用户还没有登录,显示【登录和注册的菜单】--%>
<c:if test="${empty sessionScope.user}">
<a href="pages/user/login.jsp">登录</a>
<a href="pages/user/regist.jsp">注册</a>
</c:if>
<%-- 如果已经登录,显示登录之后的用户信息--%>
<c:if test="${not empty sessionScope.user}">
<span>欢迎<span class="um_span">${sessionScope.user.username}</span>光临尚硅谷书城</span>
<a href="pages/order/order.jsp">我的订单</a>
<a href="userServlet?action=logout">注销</a>
</c:if>
<a href="pages/cart/cart.jsp">购物车</a>
<a href="pages/manager/manager.jsp">后台管理</a>
</div>
<div id="main">
<div id="book">
<div class="book_cond">
<form action="client/bookServlet" method="get">
<input type="hidden" name="action" value="pageByPrice">
价格:<input id="min" type="text" name="min" value="${param.min}">元 -
<input id="max" type="text" name="max" value="${param.max}">元
<input type="submit" value="查询"/>
</form>
</div>
<div style="...">
<span>您的购物车中有3件商品</span>
<div>
您刚刚将<span style="...">时间简史</span>加入到了购物车中
</div>
</div>
<div>
<c:forEach items="${requestScope.page.items}" var="book">
<div class="b_list">
<div class="img_div">
<img class="book_img" alt="${book.imgPath}"/>
</div>
<div class="book_info">
<div class="book_name">
<span class="sp1">书名:</span>
<span class="sp2">${book.name}</span>
</div>
<div class="book_author">
<span class="sp1">作者:</span>
<span class="sp2">${book.author}</span>
</div>
<div class= "book_price">
<span class="sp1">价格:</span>
<span class="sp2">¥${book.price}</span>
</div>
<div class="book_sales">
<span class="sp1">销量:</span>
<span class="sp2">${book.sales}</span>
</div>
<div class="book_amount">
<span class="sp1">库存:</span>
<span class="sp2">${book.stock}</span>
</div>
<div class="book_add">
<button>加入购物车:</button>
</div>
</div>
</div>
</c:forEach>
</div>
</div>
<%-- 静态包含分页条 --%>
<%@include file="/pages/common/page_nav.jsp"%>
</div>
</div>
<%--静态包含页脚内容--%>
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>
3.3、表单重复提交之——验证码
表单重复提交有三种常见的情况:
一:提交完表单。服务器使用请求转来进行页面跳转。这个时候,用户按下功能键F5,就会发起最后一次的请求。 造成表单重复提交问题。解决方法:使用重定向来进行跳转
演示
新建web模块tmp,并新建Tomcat实例tmp
index.jsp 改为 regist.jsp
<%--
Created by IntelliJ IDEA.: lenovo
Date: 2021/8/24
Time: ���� 07:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="http://localhost:8080/tmp/registServlet" method="get">
用户名:<input type="text" name="username"><br>
<input type="submit" value="注册">
</form>
</body>
</html>
新建web/ok.jsp
<%--
Created by IntelliJ IDEA.: lenovo
Date: 2021/8/24
Time: 下午 07:59
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
注册成功
</body>
</html>
src/新建com.servlet/新建registServlet
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RegistServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取用户名
String username=req.getParameter("username");
System.out.println("保存到数据库:"+username);
req.getRequestDispatcher("/ok.jsp").forward(req,resp);
}
}
多次F5,结果
解决方法:使用重定向来进行跳转
修改 RegistServlet
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RegistServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取用户名
String username=req.getParameter("username");
System.out.println("保存到数据库:"+username);
// req.getRequestDispatcher("/ok.jsp").forward(req,resp);
resp.sendRedirect(req.getContextPath()+"/ok.jsp");
}
}
二:用户正常提交服务器,但是由于网络延迟等原因,迟迟未收到服务器的响应,这个时候,用户以为提交失败, 就会着急,然后多点了几次提交操作,也会造成表单重复提交。解决:使用验证码
修改 RegistServlet
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RegistServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取用户名
String username=req.getParameter("username");
System.out.println("保存到数据库:"+username);
// req.getRequestDispatcher("/ok.jsp").forward(req,resp);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
resp.sendRedirect(req.getContextPath()+"/ok.jsp");
}
}
三:用户正常提交服务器。服务器也没有延迟,但是提交完成后,用户回退测览器。重新提交。也会造成表单重复提交。解决:使用验证码
3.4、谷歌kaptcha图片验证码的使用
谷歌验证码kaptcha使用步骤如下:
1、导入谷歌验证码的jar包
kaptcha-2.3.2.jar 下载地址
2、在web.xml中去配置用于生成验证码的Servlet程序
web.xml
<servlet>
<servlet-name>KaptchaServlet</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>KaptchaServlet</servlet-name>
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
3、在表单中使用img标签去显示验证码图片并使用它
regist.jsp
<%--
Created by IntelliJ IDEA.
User: lenovo
Date: 2021/8/24
Time: ���� 07:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="http://localhost:8080/tmp/registServlet" method="get">
用户名:<input type="text" name="username"><br>
验证码:<input type="text" style="width: 50px;" name="code">
<img src="http://localhost:8080/tmp/kaptcha.jpg" alt="" style="width: 100px;height:"><br>
<input type="submit" value="注册">
</form>
</body>
</html>
4、在服务器获取谷歌生成的验证码和客户端发送过来的验证码比较使用。
RegistServlet
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY;
public class RegistServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Session中的验证码
String token = (String) req.getSession().getAttribute(KAPTCHA_SESSION_KEY);
//删除Session中的验证码
req.getSession().removeAttribute(KAPTCHA_SESSION_KEY);
String code =req.getParameter("code");
//获取用户名
String username=req.getParameter("username");
if (token!=null&&token.equalsIgnoreCase(code)) {
System.out.println("保存到数据库:" + username);
// req.getRequestDispatcher("/ok.jsp").forward(req,resp);
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
resp.sendRedirect(req.getContextPath() + "/ok.jsp");
}else {
System.out.println("请不要重复提交表单");
}
}
}
3.5 书城项目加入验证码
web.xml配置
<servlet>
<servlet-name>KaptchaServlet</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>KaptchaServlet</servlet-name>
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
修改 regist.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>尚硅谷会员注册页面</title>
<%--静态包含 base标签,css样式,jquery文件 --%>
<%@ include file="/pages/common/head.jsp"%>
<script type="text/javascript">
//页面加载完成之后
$(function () {
//给注册绑定单击事件
$("#sub_btn").click(function () {
//验证用户名:必须由字母,数字下划线组成,并且长度为5到12位
//1获取用户名输入框里的内容
var usernameText=$("#username").val();
//2创建正则表达式对象
var usernamePatt=/^\w{5,12}$/;
//3使test方法验证
if(!usernamePatt.test(usernameText)){
//4提示用户结果
$("span.errorMsg").text("用户名不合法!");
return false;
}
//验证密码:必须由字母,数字下划线组成,并且长度为5到12位
//1获取用户名输入框里的内容
var passwordText=$("#password").val();
//2创建正则表达式对象
var passwordPatt=/^\w{5,12}$/;
//3使test方法验证
if(!passwordPatt.test(passwordText)){
//4提示用户结果
$("span.errorMsg").text("密码不合法!");
return false;
}
//验证确认密码:和密码相同
//1获取确认密码内容
var repwdText=$("#repwd").val();
//2和密码相比较
if (repwdText!=passwordText){
//3提示用户
$("span.errorMsg").text("确认密码和密码不一致!");
return false;
}
//邮箱验证:xxxxx@xxx.com
//1获取邮箱里的内容
var emailText=$("#email").val();
//2创建正则表达式对象
var emailPatt=/^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
//3使test方法验证
if(!emailPatt.test(emailText)){
//4提示用户结果
$("span.errorMsg").text("邮箱格式不合法!");
return false;
}
//验证码现在只需要验证用户已输入。因为还没讲到服务器。验证码生成。
var codeText=$("#code").val();
//去掉验证码前后空格
alert("去空格前["+codeText+"]");
codeText=$.trim(codeText);
alert("去空格后["+codeText+"]");
if (codeText==null||codeText==""){
//提示用户结果
$("span.errorMsg").text("验证码不能为空");
return false;
}
$("span.errorMsg").text("");
});
});
</script>
<style type="text/css">
.login_form {
height: 420px;
margin-top: 25px;
}
</style>
</head>
<body>
<div id="login_header">
<img class="logo_img" alt="" src="static/img/logo.gif">
</div>
<div class="login_banner">
<div id="l_content">
<span class="login_word">欢迎注册</span>
</div>
<div id="content">
<div class="login_form">
<div class="login_box">
<div class="tit">
<h1>注册尚硅谷会员</h1>
<span class="errorMsg">
<%-- <%=request.getAttribute("msg")==null?"":request.getAttribute("msg")%>--%>
${requestScope.msg}
</span>
</div>
<div class="form">
<form action="userServlet" method="post">
<input type="hidden" name="action" value="regist"/>
<label>用户名称:</label>
<input class="itxt" type="text" placeholder="请输入用户名"
<%-- value="<%=request.getAttribute("username")==null?"":request.getAttribute("username")%>"--%>
value="${requestScope.username}"
autocomplete="off" tabindex="1" name="username" id="username"/>
<br/>
<br/>
<label>用户密码:</label>
<input class="itxt" type="password" placeholder="请输入密码"
autocomplete="off" tabindex="1" name="password" id="password"/>
<br/>
<br/>
<label>确认密码:</label>
<input class="itxt" type="password" placeholder="确认密码"
autocomplete="off" tabindex="1" name="repwd" id="repwd"/>
<br/>
<br/>
<label>电子邮件:</label>
<input class="itxt" type="text" placeholder="请输入邮箱地址"
<%-- value="<%=request.getAttribute("email")==null?"":request.getAttribute("email")%>"--%>
value="${requestScope.email}"
autocomplete="off" tabindex="1" name="email" id="email"/>
<br/>
<br/>
<label>验证码:</label>
<input class="itxt" type="text" name="code" style="width: 80px;" id="code"/>
<%-- <img alt="" src="kaptcha.jpg" style="float: right;margin-right: 40px;width: 100px;height: 28px;">--%>
<img alt="" src="kaptcha.jpg" style="width: 110px;height: 30px;">
<br/>
<br/>
<input type="submit" value="注册" id="sub_btn"/>
</form>
</div>
</div>
</div>
</div>
</div>
<%--静态包含页脚内容--%>
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>
修改 UserServlet
package com.atguigu.web;
import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import com.atguigu.service.impl.UserServiceImpl;
import com.atguigu.utils.WebUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY;
public class UserServlet extends BaseServlet {
private UserService userService = new UserServiceImpl();
/**
* 登出(注销)
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void logout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、销毁Session中用户登录的信息(或者销毁Session)
req.getSession().invalidate();
// 2、重定向到首页(或登录页面)。
resp.sendRedirect(req.getContextPath());
}
/**
* 处理登录的功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
//2、调用XxxService.xxx()处理业务
User loginUser = userService.login(new User(null, username, password, null));
//如果等于null,说明登录失败
if (loginUser==null){
// 把错误信息,和回显的表单项信息,保存到Request域中
req.setAttribute("msg","用户名或密码错误!");
req.setAttribute("username",username);
// 跳回登录页面
req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);
}else {
// 成功
//保存用户登录的信息
req.getSession().setAttribute("user",loginUser);
// 跳到成功页面login_success.jsp
req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp);
}
}
/**
* 处理注册的功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Session中的验证码
String token = (String) req.getSession().getAttribute(KAPTCHA_SESSION_KEY);
//删除Session中的验证码
req.getSession().removeAttribute(KAPTCHA_SESSION_KEY);
// 1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
String code = req.getParameter("code");
// Map<String, String[]> parameterMap = req.getParameterMap();
// for (Map.Entry<String, String[]> entry:parameterMap.entrySet()) {
// System.out.println(entry.getKey()+"="+ Arrays.asList(entry.getValue()));
// }
// User user=new User();
// WebUtils.copyParamToBean(req,user);//注入赋值,与User类中setXxx对应
User user = WebUtils.copyParamToBean(req.getParameterMap(),new User());//注入赋值,与User类中setXxx对应
// 2、检查验证码是否正确 ===写死,要求验证码为:abcde
if (token!=null&&token.equalsIgnoreCase(code)){
// 3、检查用户名是否可用
if (userService.existUsername(username)){
System.out.println("用户名["+username+"]已存在!");
// 把回显信息保存到Request域中
req.setAttribute("msg","用户名已存在!!");
req.setAttribute("username",username);
req.setAttribute("email",email);
// 跳回注册页面
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}else {
// 可用 调用Service保存到数据库
userService.registUser(new User(null,username,password,email));
// 跳到注册成功束面regist_success.jsp
req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp);
}
}else {
// 把回显信息保存到Request域中
req.setAttribute("msg","验证码错误!!");
req.setAttribute("username",username);
req.setAttribute("email",email);
System.out.println("验证码["+code+"]错误,");
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}
}
}
3.6、验证码的切换
修改 regist.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>尚硅谷会员注册页面</title>
<%--静态包含 base标签,css样式,jquery文件 --%>
<%@ include file="/pages/common/head.jsp"%>
<script type="text/javascript">//页面加载完成之后
$(function () {
//给验证码的图片,绑定单击事件
$("#code_img").click(function (){
//在事件响应的function函数中有一个this对象。这个this对象,是当前正在响应事件的dom对象
//src表示验证码img标签的图片路径。它可读可写。
// alert(this.src);
this.src="${basePath}kaptcha.jpg?d="+new Date();
});
//给注册绑定单击事件
$("#sub_btn").click(function () {
//验证用户名:必须由字母,数字下划线组成,并且长度为5到12位
//1获取用户名输入框里的内容
var usernameText=$("#username").val();
//2创建正则表达式对象
var usernamePatt=/^\w{5,12}$/;
//3使test方法验证
if(!usernamePatt.test(usernameText)){
//4提示用户结果
$("span.errorMsg").text("用户名不合法!");
return false;
}
//验证密码:必须由字母,数字下划线组成,并且长度为5到12位
//1获取用户名输入框里的内容
var passwordText=$("#password").val();
//2创建正则表达式对象
var passwordPatt=/^\w{5,12}$/;
//3使test方法验证
if(!passwordPatt.test(passwordText)){
//4提示用户结果
$("span.errorMsg").text("密码不合法!");
return false;
}
//验证确认密码:和密码相同
//1获取确认密码内容
var repwdText=$("#repwd").val();
//2和密码相比较
if (repwdText!=passwordText){
//3提示用户
$("span.errorMsg").text("确认密码和密码不一致!");
return false;
}
//邮箱验证:xxxxx@xxx.com
//1获取邮箱里的内容
var emailText=$("#email").val();
//2创建正则表达式对象
var emailPatt=/^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
//3使test方法验证
if(!emailPatt.test(emailText)){
//4提示用户结果
$("span.errorMsg").text("邮箱格式不合法!");
return false;
}
//验证码现在只需要验证用户已输入。因为还没讲到服务器。验证码生成。
var codeText=$("#code").val();
//去掉验证码前后空格
alert("去空格前["+codeText+"]");
codeText=$.trim(codeText);
alert("去空格后["+codeText+"]");
if (codeText==null||codeText==""){
//提示用户结果
$("span.errorMsg").text("验证码不能为空");
return false;
}
$("span.errorMsg").text("");
});
});</script>
<style type="text/css">.login_form {
height: 420px;
margin-top: 25px;
}</style>
</head>
<body>
<div id="login_header">
<img class="logo_img" alt="" src="static/img/logo.gif">
</div>
<div class="login_banner">
<div id="l_content">
<span class="login_word">欢迎注册</span>
</div>
<div id="content">
<div class="login_form">
<div class="login_box">
<div class="tit">
<h1>注册尚硅谷会员</h1>
<span class="errorMsg">
<%-- <%=request.getAttribute("msg")==null?"":request.getAttribute("msg")%>--%>
${requestScope.msg}
</span>
</div>
<div class="form">
<form action="userServlet" method="post">
<input type="hidden" name="action" value="regist"/>
<label>用户名称:</label>
<input class="itxt" type="text" placeholder="请输入用户名"
<%-- value="<%=request.getAttribute("username")==null?"":request.getAttribute("username")%>"--%>
value="${requestScope.username}"
autocomplete="off" tabindex="1" name="username" id="username"/>
<br/>
<br/>
<label>用户密码:</label>
<input class="itxt" type="password" placeholder="请输入密码"
autocomplete="off" tabindex="1" name="password" id="password"/>
<br/>
<br/>
<label>确认密码:</label>
<input class="itxt" type="password" placeholder="确认密码"
autocomplete="off" tabindex="1" name="repwd" id="repwd"/>
<br/>
<br/>
<label>电子邮件:</label>
<input class="itxt" type="text" placeholder="请输入邮箱地址"
<%-- value="<%=request.getAttribute("email")==null?"":request.getAttribute("email")%>"--%>
value="${requestScope.email}"
autocomplete="off" tabindex="1" name="email" id="email"/>
<br/>
<br/>
<label>验证码:</label>
<input class="itxt" type="text" name="code" style="width: 80px;" id="code"/>
<%-- <img alt="" src="kaptcha.jpg" style="float: right;margin-right: 40px;width: 100px;height: 28px;">--%>
<img id="code_img" alt="" src="kaptcha.jpg" style="width: 110px;height: 30px;">
<br/>
<br/>
<input type="submit" value="注册" id="sub_btn"/>
</form>
</div>
</div>
</div>
</div>
</div>
<%--静态包含页脚内容--%>
<%@include file="/pages/common/footer.jsp"%>
</body>
</html>
修改 UserServlet
package com.atguigu.web;
import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import com.atguigu.service.impl.UserServiceImpl;
import com.atguigu.utils.WebUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY;
public class UserServlet extends BaseServlet {
private UserService userService = new UserServiceImpl();
/**
* 登出(注销)
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void logout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、销毁Session中用户登录的信息(或者销毁Session)
req.getSession().invalidate();
// 2、重定向到首页(或登录页面)。
resp.sendRedirect(req.getContextPath());
}
/**
* 处理登录的功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
//2、调用XxxService.xxx()处理业务
User loginUser = userService.login(new User(null, username, password, null));
//如果等于null,说明登录失败
if (loginUser==null){
// 把错误信息,和回显的表单项信息,保存到Request域中
req.setAttribute("msg","用户名或密码错误!");
req.setAttribute("username",username);
// 跳回登录页面
req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);
}else {
// 成功
//保存用户登录的信息
req.getSession().setAttribute("user",loginUser);
// 跳到成功页面login_success.jsp
req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp);
}
}
/**
* 处理注册的功能
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Session中的验证码
String token = (String) req.getSession().getAttribute(KAPTCHA_SESSION_KEY);
//删除Session中的验证码
req.getSession().removeAttribute(KAPTCHA_SESSION_KEY);
// 1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
String code = req.getParameter("code");
// Map<String, String[]> parameterMap = req.getParameterMap();
// for (Map.Entry<String, String[]> entry:parameterMap.entrySet()) {
// System.out.println(entry.getKey()+"="+ Arrays.asList(entry.getValue()));
// }
// User user=new User();
// WebUtils.copyParamToBean(req,user);//注入赋值,与User类中setXxx对应
User user = WebUtils.copyParamToBean(req.getParameterMap(),new User());//注入赋值,与User类中setXxx对应
// 2、检查验证码是否正确 ===写死,要求验证码为:abcde
if (token!=null&&token.equalsIgnoreCase(code)){
// 3、检查用户名是否可用
if (userService.existUsername(username)){
System.out.println("用户名["+username+"]已存在!");
// 把回显信息保存到Request域中
req.setAttribute("msg","用户名已存在!!");
req.setAttribute("username",username);
req.setAttribute("email",email);
// 跳回注册页面
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}else {
// 可用 调用Service保存到数据库
userService.registUser(new User(null,username,password,email));
// 跳到注册成功束面regist_success.jsp
req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp);
}
}else {
// 把回显信息保存到Request域中
req.setAttribute("msg","验证码错误!!");
req.setAttribute("username",username);
req.setAttribute("email",email);
System.out.println("验证码["+code+"]错误,");
req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
}
}
}