前言:此项目篇是对基础知识的复习与巩固,不涉及后端框架的知识,仅使用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]+@[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]+@[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);
UserDaoImpl
/**
* 通过用户名密码查找用户
* @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");
}
}