当前位置:网站首页>某马旅游网站开发(登录注册退出功能的实现)
某马旅游网站开发(登录注册退出功能的实现)
2022-07-07 21:58:00 【豪豪喜欢吃猪肉】
前言:此项目篇是对基础知识的复习与巩固,不涉及后端框架的知识,仅使用maven项目管理工具
技术选型
- 网络层
- servlet:前端控制器
- html:视图
- filter:过滤器
- beanUtils:数据封装
- jackson:json序列化工具
- 服务层
- javamail:java发送邮件工具
- redis:nosql内存数据库
- jedis:java的redis客户端
- dao层
- mysql:数据库
- druid:数据库连接池
- jdbcTemplate:jdbc工具
目录
0.2.2编写UserService以及UserServiceImpl
0.注册功能实现
0.0准备
各级文件创建如下
0.0.0用户实体类创建
package com.sixstar.travel.domain;
import java.io.Serializable;
/**
* 用户实体类
*/
public class User implements Serializable {
private int uid;//用户id
private String username;//用户名,账号
private String password;//密码
private String name;//真实姓名
private String birthday;//出生日期
private String sex;//男或女
private String telephone;//手机号
private String email;//邮箱
private String status;//激活状态,Y代表激活,N代表未激活
private String code;//激活码(要求唯一)
/**
* 无参构造方法
*/
public User() {
}
/**
* 有参构方法
* @param uid
* @param username
* @param password
* @param name
* @param birthday
* @param sex
* @param telephone
* @param email
* @param status
* @param code
*/
public User(int uid, String username, String password, String name, String birthday, String sex, String telephone, String email, String status, String code) {
this.uid = uid;
this.username = username;
this.password = password;
this.name = name;
this.birthday = birthday;
this.sex = sex;
this.telephone = telephone;
this.email = email;
this.status = status;
this.code = code;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
.............................
public void setCode(String code) {
this.code = code;
}
}
0.0.1用户表的创建
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`uid` int(0) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`password` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`birthday` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`sex` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`telephone` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`email` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`status` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`uid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
0.0.2注册前端页面效果
0.0.3前端注册界面代码(js部分)
/* 表单效验 :
* username:/^\w{8,20}/
* password:/^\w{8,20}/
* email:/^[A-Za-z0-9\u4e00-\u9fa5][email protected][a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
* */
// 用户名效验
function checkUsername(){
var username = $("#username").val();
var reg_username = /^\w{8,20}/;
var flog = reg_username.test(username);
if (flog){
$("#username").css("border","")
}else{
$("#username").css("border","1px solid red")
}
return flog;
}
// 密码效验
function checkPassword(){
var password = $("#password").val();
var reg_password = /^\w{8,20}/;
var flog = reg_password.test(password);
if (flog){
$("#password").css("border","")
}else{
$("#password").css("border","1px solid red")
}
return flog;
}
// 邮箱效验
function checkEmail(){
var email = $("#email").val();
var reg_email = /^[A-Za-z0-9\u4e00-\u9fa5][email protected][a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
var flog = reg_email.test(email);
if (flog){
$("#email").css("border","")
}else{
$("#email").css("border","1px solid red")
}
return flog;
}
// 表单校验函数
function checkAll() {
return checkUsername()&&checkPassword()&&checkEmail();
}
// 绑定离焦事件
$("#username").blur(checkUsername());
$("#password").blur(checkPassword());
$("#email").blur(checkEmail());
$(function () {
$("#registerForm").submit(function () {
if(checkAll()){
// 表单项全部验证通过
$.post("registUserServlet",$(this).serialize(),function (data) {
if(data.flag){
location.href="register_ok.html";
}else {
$("#errorMsg").html(data.errorMsg);
}
});
}
// 表单项验证失败,拦截提交请求
return false;
})
})
0.1.0注册逻辑分析
0.2.0后端代码实现
0.2.1编写UserDao以及UserDaoimp
UserDao
package com.haohao.travel.dao;
import com.haohao.travel.domain.User;
public interface UserDao {
/**
* 根据用户名查询用户信息
* @param username
* @return
*/
User findByUsername(String username);
/**
* 保存用户信息
* @param user
*/
void save(User user);
/**
* 通过激活码查找用户
* @param code
* @return
*/
User findByCode(String code);
/**
* 修改状态码
* @param user
*/
void updataStatus(User user);
}
UserDaoimp
package com.haohao.travel.dao.impl;
import com.haohao.travel.dao.UserDao;
import com.haohao.travel.domain.User;
import com.haohao.travel.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
public class UserDaoImpl implements UserDao {
// 定义数据库模板,配合Bean对象用于把从数据库中查询出来的列转换为对象
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 通过用户名查找用户
* @param username
* @return
*/
@Override
public User findByUsername(String username) {
User user = null;
try{
// 定义sql
String sql = "select * from user where username=?";
// 执行sql
user = template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),username);
}catch (Exception e){
}
return user;
}
/**
* 通过user对象保存至数据库中
* @param user
*/
@Override
public void save(User user) {
//1.定义sql
String sql = "insert into user(username,password,name,birthday,sex,telephone,email,status,code) values(?,?,?,?,?,?,?,?,?)";
// 执行sql
template.update(sql,user.getUsername(), user.getPassword(), user.getName(), user.getBirthday(), user.getSex(), user.getTelephone(), user.getEmail(), user.getStatus(), user.getCode() );
}
/**
* 通过激活码查找用户信息
* @param code
* @return
*/
@Override
public User findByCode(String code) {
User user = null;
try{
// 定义sql
String sql = "select * from user where code=?";
// 执行sql
user = template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),code);
}catch (Exception e){
}
return user;
}
/**
* 修改用户的激活状态
* @param user
*/
@Override
public void updataStatus(User user) {
String sql = " update user set status = 'Y' where uid=?";
template.update(sql,user.getUid());
}
}
0.2.2编写UserService以及UserServiceImpl
UserService
package com.haohao.travel.service;
import com.haohao.travel.domain.User;
public interface UserService {
/**
* 用户注册
* @param user
* @return
*/
boolean regist(User user);
/**
* 用户激活
* @param code
* @return
*/
boolean active(String code);
}
UserServiceImpl
package com.haohao.travel.service.impl;
import com.haohao.travel.dao.UserDao;
import com.haohao.travel.dao.impl.UserDaoImpl;
import com.haohao.travel.domain.User;
import com.haohao.travel.service.UserService;
import com.haohao.travel.util.MailUtils;
import com.haohao.travel.util.UuidUtil;
public class UserServiceImpl implements UserService {
// 用户dao对象
private UserDao userDao = new UserDaoImpl();
@Override
public boolean regist(User user) {
User u = userDao.findByUsername(user.getUsername());
if (u!=null){
// 该用户名与已存在,注册失败
return false;
}
// 用户名不存在,保存用户到数据库
// 设置激活码与激活状态
user.setCode(UuidUtil.getUuid());
user.setStatus("N");
userDao.save(user);
// 发送激活邮件
String text = "<a href='http://localhost/travel/activeUserServlet?code="+user.getCode()+"'></a>";
MailUtils.sendMail(user.getEmail(),text,"激活邮件");
return true;
}
@Override
public boolean active(String code) {
User user = userDao.findByCode(code);
if (user!=null){
// 修改这个用户的激活状态
userDao.updataStatus(user);
return true;
}
return false;
}
}
0.2.3编写RegistUserServlet
package com.haohao.travel.web.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.haohao.travel.domain.ResultInfo;
import com.haohao.travel.domain.User;
import com.haohao.travel.service.UserService;
import com.haohao.travel.service.impl.UserServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
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;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
@WebServlet("/registUserServlet")
public class RegistUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 图片验证码效验
String check = req.getParameter("check");
HttpSession session = req.getSession();
String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");
// 图片验证码用过一次即失效
session.removeAttribute("CHECKCODE_SERVER");
if (checkcode_server==null||!checkcode_server.equals(check)){
// 图片验证码校验失败
// 结果信息对象,存储需要返回给前端的数据
ResultInfo info = new ResultInfo(false,"验证码错误");
// 将信息结果对象转换为json格式
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
// 设置响应头为json格式
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(json);
return;
}
// 图形验证码校验成功,获取请求中的user信息,封装为user对象
Map<String,String[]> map = req.getParameterMap();
User user = new User();
try{
BeanUtils.populate(user,map);
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
// 调用UserService中的注册进行注册
UserService userService = new UserServiceImpl();
boolean flag = userService.regist(user);
ResultInfo info = null;
if (flag){
// 注册成功
info = new ResultInfo(true);
}else {
info = new ResultInfo(false,"注册失败");
}
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
// 设置响应头为json格式
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(json);
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.doPost(req,resp);
resp.setStatus(404);
resp.getWriter().write("请求方式非法");
}
}
0.2.4编写ActiveUserServlet
package com.haohao.travel.web.servlet;
import com.haohao.travel.service.UserService;
import com.haohao.travel.service.impl.UserServiceImpl;
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 ActiveUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.doGet(req,resp);
resp.getWriter().write("非法访问");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg ="激活失败,请检查激活码是否有效";
String code = req.getParameter("code");
if (code!=null){
UserService userService = new UserServiceImpl();
boolean flag = userService.active(code);
if (flag){
// 激活成功
msg = "激活成功,请<a href='login.html'>登录</a>!";
}
}
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write(msg);
}
}
1.登录功能实现
1.0分析
1.0.0页面效果
1.1代码实现
1.1.0dao层
userdao
/**
*
* 根据用户名与密码查找用户
* @param username
* @param password
* @return
*/
User findByUsernameAndPassword(String username,String password);
/**
* 通过用户名密码查找用户
* @param username
* @param password
* @return
*/
@Override
public User findByUsernameAndPassword(String username, String password) {
User user =null;
try{
// 定义sql
String sql = "select * from tab_user where username=? and password=?";
// 执行sql
user = template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),username,password);
}catch (Exception e){
}
return user;
}
1.1.1server层
userServer
/**
* 用户登录
* @param user
* @return
*/
User login(User user);
userServerImpl
/**
* 用户登录
* @param user
* @return
*/
@Override
public User login(User user) {
return userDao.findByUsernameAndPassword(user.getUsername(),user.getPassword()); ;
}
1.1.2web层
LoginUserServlet
package com.haohao.travel.web.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.haohao.travel.domain.ResultInfo;
import com.haohao.travel.domain.User;
import com.haohao.travel.service.UserService;
import com.haohao.travel.service.impl.UserServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
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;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
@WebServlet("/loginServlet")
public class LoginUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 图片验证码效验
String check = req.getParameter("check");
HttpSession session = req.getSession();
String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");
// 图片验证码用过一次即失效
session.removeAttribute("CHECKCODE_SERVER");
if (checkcode_server==null||!checkcode_server.equals(check)){
// 图片验证码校验失败
// 结果信息对象,存储需要返回给前端的数据
ResultInfo info = new ResultInfo(false,"验证码错误");
// 将信息结果对象转换为json格式
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
// 设置响应头为json格式
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(json);
return;
}
// 图形验证码校验成功,获取请求中的user信息,封装为user对象
Map<String,String[]> map = req.getParameterMap();
User user = new User();
try{
BeanUtils.populate(user,map);
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
// 调用UserService中的登录进行登录
UserService userService = new UserServiceImpl();
// 登陆后的user对象,为null则登陆失败
user = userService.login(user);
ResultInfo info = new ResultInfo();
if (user==null){
// 登陆失败
info.setFlag(false);
info.setErrorMsg("用户名或密码不正确");
}else if(user.getStatus().equals("N")){
// 用户未激活
info.setFlag(false);
info.setErrorMsg("请前往邮箱进行激活");
}else {
// 成功登录,状态保持
req.getSession().setAttribute("user",user);
info.setFlag(true);
}
// 响应json数据
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(json);
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.doPost(req,resp);
resp.getWriter().write("非法访问");
}
}
findUserServlet
package com.haohao.travel.web.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.haohao.travel.domain.ResultInfo;
import com.haohao.travel.domain.User;
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 java.io.IOException;
@WebServlet("/findUserServlet")
public class FindUserServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
User user = null;
try{
user= (User) req.getSession().getAttribute("user");
}catch (Exception e){
}
ResultInfo info=new ResultInfo();
if(user!=null){
// 登陆过的
info.setFlag(true);
info.setData(user.getUsername());
}else {
info.setFlag(false);
}
ObjectMapper mapper=new ObjectMapper();
String json = mapper.writeValueAsString(info);
// 设置响应头为json格式
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(json);
}
}
1.1.3前端代码
登陆页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>黑马旅游网-登录</title>
<link rel="stylesheet" type="text/css" href="css/common.css">
<link rel="stylesheet" type="text/css" href="css/login.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<!--导入angularJS文件-->
<script src="js/angular.min.js"></script>
<!--导入jquery-->
<script src="js/jquery-3.3.1.js"></script>
<script>
$(function () {
$("#btn_sub").submit(function () {
$.post("loginServlet",$("#loginForm").serialize(),function (data) {
if (data.flag){
// 登陆成功,跳转到首页
location.href="index.html"
}else {
// 登陆失败
$("#errorMsg").html(data.errorMsg);
return false;
}
});
});
});
</script>
</head>
<body>
<!--引入头部-->
<div id="header"></div>
<!-- 头部 end -->
<section id="login_wrap">
<div class="fullscreen-bg" style="background: url(images/login_bg.png);height: 532px;">
</div>
<div class="login-box">
<div class="title">
<img src="images/login_logo.png" alt="">
<span>欢迎登录黑马旅游账户</span>
</div>
<div class="login_inner">
<!--登录错误提示消息-->
<div id="errorMsg" class="alert alert-danger" ></div>
<form id="loginForm" action="" method="post" accept-charset="utf-8">
<input type="hidden" name="action" value="login"/>
<input name="username" type="text" placeholder="请输入账号" autocomplete="off">
<input name="password" type="text" placeholder="请输入密码" autocomplete="off">
<div class="verify">
<input name="check" type="text" placeholder="请输入验证码" autocomplete="off">
<span><img src="checkCode" alt="" onclick="changeCheckCode(this)"></span>
<script type="text/javascript">
//图片点击事件
function changeCheckCode(img) {
img.src="checkCode?"+new Date().getTime();
}
</script>
</div>
<div class="submit_btn">
<button type="button" id="btn_sub">登录</button>
<div class="auto_login">
<input type="checkbox" name="" class="checkbox">
<span>自动登录</span>
</div>
</div>
</form>
<div class="reg">没有账户?<a href="javascript:;">立即注册</a></div>
</div>
</div>
</section>
<!--引入尾部-->
<div id="footer"></div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="js/jquery-1.11.0.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
<!--导入布局js,共享header和footer-->
<script type="text/javascript" src="js/include.js"></script>
</body>
</html>
首页昵称显示
<script>
// 获取登陆用户名
$(function () { $.get("findUserServlet",{},function (data) {
//{uid:1,name:'李四'}
if(data.flag){
// 已登陆
var msg = "欢迎回来,"+data.name;
$("#span_username").html(msg);
$(".login_out").hide()
$(".login").show()
}else {
// 未登录
$(".login").hide()
$(".login_out").show()
}
});
});
</script>
2.退出功能实现
2.0准备
2.0.0页面效果
点击退出之后删除登录信息,并跳转到登陆界面
2.1前端代码实现
2.1.0修改header.html
<a href="javascript:location.href='exitServlet';">退出</a>
2.2后端代码实现
2.2.0exitServlet
package com.haohao.travel.web.servlet;
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 java.io.IOException;
@WebServlet("/exitServlet")
public class ExitUserServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 销毁登陆数据
req.getSession().invalidate();
// 跳转登陆界面
resp.sendRedirect(req.getContextPath()+"/login.html");
}
}
边栏推荐
- The function is really powerful!
- MP4文件格式解析之结合实例分析
- 每日刷题记录 (十六)
- 自动化测试:Robot FrameWork框架90%的人都想知道的实用技巧
- 数据库查询——第几高的数据?
- Common selectors are
- ROS from entry to mastery (IX) initial experience of visual simulation: turtlebot3
- Chisel tutorial - 01 Introduction to Scala
- Introduction knowledge system of Web front-end engineers
- How does starfish OS enable the value of SFO in the fourth phase of SFO destruction?
猜你喜欢
串联二极管,提高耐压
[question de programmation] [scratch niveau 2] oiseaux volants en décembre 2019
95. (cesium chapter) cesium dynamic monomer-3d building (building)
UIC564-2 附录4 –阻燃防火测试:火焰的扩散
ROS从入门到精通(九) 可视化仿真初体验之TurtleBot3
第四期SFO销毁,Starfish OS如何对SFO价值赋能?
Kubectl 好用的命令行工具:oh-my-zsh 技巧和窍门
关于组织2021-2022全国青少年电子信息智能创新大赛西南赛区(四川)复赛的通知
How to measure whether the product is "just needed, high frequency, pain points"
Flash download setup
随机推荐
正畸注意事项(持续更新中)
Database interview questions + analysis
MP4文件格式解析之结合实例分析
Apng2gif solutions to various problems
Is it safe for tongdaxin to buy funds?
One click free translation of more than 300 pages of PDF documents
【編程題】【Scratch二級】2019.12 飛翔的小鳥
AITM3.0005 烟雾毒性测试
@Configuration注解的详细介绍
Robomaster visual tutorial (1) camera
At the age of 35, I made a decision to face unemployment
Traduction gratuite en un clic de plus de 300 pages de documents PDF
About the difference between ch32 library function and STM32 library function
Problems faced when connecting to sqlserver after downloading (I)
一鍵免費翻譯300多頁的pdf文檔
How to measure whether the product is "just needed, high frequency, pain points"
go time包常用函数
Redis caching tool class, worth owning~
自动化测试:Robot FrameWork框架90%的人都想知道的实用技巧
mysql8.0 ubuntu20.4