1. Import the initialized maven project
The import method can refer to the link below:
How to import an existing Maven project with Eclipse - Programmer Sought
After importing and starting the static page of the initialized maven project
2. Create a database
/*==============================================================*/
/* DBMS name: MySQL 5.0 */
/* Created on: 2018/2/14 23:10:29 */
/*==============================================================*/
create database travel
set names utf8;
drop table if exists tab_favorite;
drop table if exists tab_route_img;
drop table if exists tab_route;
drop table if exists tab_category;
drop table if exists tab_seller;
drop table if exists tab_user;
/*==============================================================*/
/* Table: tab_category */
/*==============================================================*/
create table tab_category
(
cid int not null auto_increment,
cname varchar(100) not null,
primary key (cid),
unique key AK_nq_categoryname (cname)
);
/*==============================================================*/
/* Table: tab_favorite */
/*==============================================================*/
create table tab_favorite
(
rid int not null,
date date not null,
uid int not null,
primary key (rid, uid)
);
/*==============================================================*/
/* Table: tab_route */
/*==============================================================*/
create table tab_route
(
rid int not null auto_increment,
rname varchar(500) not null,
price double not null,
routeIntroduce varchar(1000),
rflag char(1) not null,
rdate varchar(19),
isThemeTour char(1) not null,
count int default 0,
cid int not null,
rimage varchar(200),
sid int,
sourceId varchar(50),
primary key (rid),
unique key AK_nq_sourceId (sourceId)
);
/*==============================================================*/
/* Table: tab_route_img */
/*==============================================================*/
create table tab_route_img
(
rgid int not null auto_increment,
rid int not null,
bigPic varchar(200) not null,
smallPic varchar(200),
primary key (rgid)
);
/*==============================================================*/
/* Table: tab_seller */
/*==============================================================*/
create table tab_seller
(
sid int not null auto_increment,
sname varchar(200) not null,
consphone varchar(20) not null,
address varchar(200),
primary key (sid),
unique key AK_Key_2 (sname)
);
/*==============================================================*/
/* Table: tab_user */
/*==============================================================*/
create table tab_user
(
uid int not null auto_increment,
username varchar(100) not null,
password varchar(32) not null,
name varchar(100),
birthday date,
sex char(1),
telephone varchar(11),
email varchar(100),
status char(1) ,
code varchar(50),
primary key (uid),
unique key AK_nq_username (username),
unique key AK_nq_code (code)
);
alter table tab_favorite add constraint FK_route_favorite foreign key (rid)
references tab_route (rid) on delete restrict on update restrict;
alter table tab_favorite add constraint FK_user_favorite foreign key (uid)
references tab_user (uid) on delete restrict on update restrict;
alter table tab_route add constraint FK_category_route foreign key (cid)
references tab_category (cid) on delete restrict on update restrict;
alter table tab_route add constraint FK_seller_route foreign key (sid)
references tab_seller (sid) on delete restrict on update restrict;
alter table tab_route_img add constraint FK_route_routeimg foreign key (rid)
references tab_route (rid) on delete restrict on update restrict;
insert into `tab_category`(`cid`,`cname`) values (8,'全球自由行'),(5,'国内游'),(4,'处境游'),(7,'抱团定制'),(6,'港澳游'),(2,'酒店'),(1,'门票'),(3,'香港车票');
insert into `tab_seller`(`sid`,`sname`,`consphone`,`address`) values (1,'黑马程序员','12345678901','传智播客javaEE学院');
/*Data for the table `tab_route` */
3. Code development
3.1 Development of registration and login functions
learning target
1. Be able to complete the project registration function
2. Be able to complete the email login function
study guide
- Form Validation for Registration Function
- Verification code verification of registration function
- Email activation for the registration function
- Implementation of the login function
3.1.1 Registration function analysis
1. Front-end page function realization
*Use js to complete form validation
* Use ajax to complete the form submission
*After successful registration, the redirected page success.html
1.1 Form verification function
①User name: word characters, length 8-20 (of course, it can also be designed to check whether it is a Chinese or English name)
②Password: Word characters, length 8-20 characters
③email: email format
④Name: not empty
⑤Mobile phone number: format of mobile phone number
⑥Date of Birth: not empty
⑦Verification code: not empty
1.2 Code writing
Form various verification js codes can refer to: JS commonly used form verification (number, length, Chinese characters, email, mobile phone number, ID card, etc.)_Endless silent blog-CSDN blog_js form verification ID card
ajax is used to verify the correctness of the form
①User name verification
用正则表达式校验账号密码是否符合规范
function checkUsername() {
//1.获取用户名值
var username = $("#username").val();
//2.定义正则
var reg_username = /^\w{8,20}$/;
//3.判断,给出提示信息
var flag = reg_username.test(username);
if(flag){
//用户名合法
$("#username").css("border","");
}else{
//用户名非法,加一个红色边框
$("#username").css("border","1px solid red");
}
return flag;
}
②Password verification
//校验密码
function checkPassword() {
//1.获取用户名值
var password = $("#password").val();
//2.定义正则
var reg_password = /^\w{8,20}$/;
//3.判断,给出提示信息
var flag = reg_password.test(password);
if(flag){
//用户名合法
$("#password").css("border","");
}else{
//用户名非法,加一个红色边框
$("#password").css("border","3px solid red");
}
return flag;
}
③ Email verification
//校验电子邮件
function checkEmail() {
//1.获取用户名值
var email = $("#email").val();
//2.定义正则
//对电子邮件的验证
var reg_email = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
//3.判断,给出提示信息
var flag = reg_email.test(email);
if(flag){
//用户名合法
$("#email").css("border","");
}else{
//用户名非法,加一个红色边框
$("#email").css("border","3px solid red");
}
return flag;
}
//校验电子邮件
function checkEmail() {
//1.获取用户名值
var email = $("#email").val();
//2.定义正则
//对电子邮件的验证
var reg_email = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
//3.判断,给出提示信息
var flag = reg_email.test(email);
if(flag){
//用户名合法
$("#email").css("border","");
}else{
//用户名非法,加一个红色边框
$("#email").css("border","3px solid red");
}
return flag;
}
//检验姓名(中文)
function checkName() {
//1.获取姓名值
var name=$("#name").val();
//2.定义正则
//对姓名进行验证
var reg_name =/^[\u0391-\uFFE5]+$/;
//3.判断,给出提示信息
var flag = reg_name.test(name);
if(flag){
//用户名合法
$("#name").css("border","");
}else{
//用户名非法,加一个红色边框
$("#name").css("border","3px solid red");
}
return flag;
}
//检验手机号
function checkTelephone() {
//1.获取姓名值
var telephone=$("#telephone").val();
//2.定义正则
//对姓名进行验证
var reg_telephone =/^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;;
//3.判断,给出提示信息
var flag = reg_telephone.test(telephone);
if(flag&&(telephone.length==11)){
//手机号合法
$("#telephone").css("border","");
}else{
//手机号非法,加一个红色边框
$("#telephone").css("border","3px solid red");
}
return flag;
}
//检验出生日期
function checkBirthday() {
//1.获取出生日期
var birthday=$("#birthday").val();
var date1=birthday.replace(/-/g,"/");//替换字符,变成标准格式(检验格式为:'2009-12-10')
// var obj_value=obj.replace("-","/");//替换字符,变成标准格式(检验格式为:'2010-12-10 11:12')
var date1=new Date(Date.parse(date1));
print(date1)
var date2=new Date();//取今天的日期
//3.判断,给出提示信息
if(date1>date2){
//日期非法,加一个红色边框
$("#birthday").css("border","3px solid red");
return false;
}
else{
$("#birthday").css("border","");
return true;
}
}
Ajax validation
//ajax校验
$(function() {
$("#registerForm").submit(function() {
return checkUsername()&&checkPassword();
});
//当某一个组件失去焦点时,调用对应的校验方法
$("#username").blur(checkUsername);
$("#password").blur(checkPassword);
$("#email").blur(checkEmail);
$("#name").blur(checkName);
$("#telephone").blur(checkTelephone);
$("#birthday").blur(checkBirthday);
});
2. Writing back-end code
First write the controller RegistUserServlet of the web layer, which is used to receive the front-end request data information, and then hand it over to the service layer for processing
package cn.itcast.travel.web.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
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 org.apache.commons.beanutils.BeanUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.itcast.travel.dao.impl.UserDaoImpl;
import cn.itcast.travel.domain.ResultInfo;
import cn.itcast.travel.domain.User;
import cn.itcast.travel.service.UserService;
import cn.itcast.travel.service.impl.UserServiceImpl;
/**
* Servlet implementation class RegistUserServlet
*/
@WebServlet("/registUserServlet")
public class RegistUserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取前端的数据
Map<String, String[]> map=request.getParameterMap();
//2.封装对象
User user=new User();
try {
BeanUtils.populate(user, map); //将map中的字典封装成user
} catch (IllegalAccessException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(user);
//3.调用service层的函数来完成注册
UserService userService=new UserServiceImpl();
boolean flag=userService.regist(user);
ResultInfo info=new ResultInfo(); //返回的结果封装info对象
//4.响应结果
if(flag) { //注册成功
info.setFlag(true);
}
else { //注册失败
info.setErrorMsg("注册失败!");
info.setFlag(false);
System.out.println("注册失败");
}
//将info对象序列化成json
ObjectMapper oMapper=new ObjectMapper();
String json=oMapper.writeValueAsString(info);
//将json字符串回写到客户端
//设置content-type
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
}
}
The userservice interface in the service layer and its implementation class userserviceImpl are written
package cn.itcast.travel.service;
import cn.itcast.travel.domain.User;
public interface UserService {
//注册用户
public boolean regist(User user);
}
package cn.itcast.travel.service.impl;
import cn.itcast.travel.dao.UserDao;
import cn.itcast.travel.dao.impl.UserDaoImpl;
import cn.itcast.travel.domain.User;
import cn.itcast.travel.service.UserService;
public class UserServiceImpl implements UserService {
//注册用户
@Override
public boolean regist(User user) {
// 通过用户名来查询用户信息
UserDao uDao=new UserDaoImpl();
User user2=uDao.findByUsername(user.getUsername());
if(user2!=null) {
//说明已经注册了信息,用户名注册失败
return false;
}
//没有注册,保存用户的信息
uDao.save(user);
return true;
}
}
The userdao interface in the DAO layer and its implementation class userdaoImpl are written
package cn.itcast.travel.dao;
import cn.itcast.travel.domain.User;
public interface UserDao {
//根据用户名来查询用户信息
public User findByUsername(String username);
//用户信息保存
public void save(User user);
}
package cn.itcast.travel.dao.impl;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import cn.itcast.travel.util.JDBCUtils;
import cn.itcast.travel.dao.UserDao;
import cn.itcast.travel.domain.User;
public class UserDaoImpl implements UserDao {
//操作数据库的对象
private JdbcTemplate jdbcTemplate=new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public User findByUsername(String username) {
//根据用户名来查询用户信息
User user=null;
try {//这个trycatch是为了防止jdbctemplate查询时没查到用户,封装用户会出异常,不是返回null 而设置的
// 1.编写sql语句
String sql="select* from tab_user where username = ?";
//2.执行sql语句
user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),username);
} catch (DataAccessException e) {
}
return user;
}
@Override
public void save(User user) {
// 1.定义sql
String sql="insert into tab_user(username,password,name,birthday,sex,telephone,email) values(?,?,?,?,?,?,?)";
//2.执行sql语句
jdbcTemplate.update(sql,user.getUsername(),
user.getPassword(),
user.getName(),
user.getBirthday(),
user.getSex(),
user.getTelephone(),
user.getEmail()
);
}
}
So far, the functional principle of registration is basically completed
other:
The method of obtaining the connection pool object is written in the JDBCUtils class, which will not be elaborated here
jdbc jar package connected to the database and js-related jar packages, which are omitted here
3. The background verification code and the processing of the returned data by the foreground
We only need to write in the controller RegistUserServlet of the web layer to receive the verification code value from the client and the session domain value from checkCodeServlet, and then compare the two. If they are not the same, set the result object information as the verification code error, and set The result object is serialized into json and returned to the client for display
RegistUserServlet
package cn.itcast.travel.web.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
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 org.apache.commons.beanutils.BeanUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.itcast.travel.dao.impl.UserDaoImpl;
import cn.itcast.travel.domain.ResultInfo;
import cn.itcast.travel.domain.User;
import cn.itcast.travel.service.UserService;
import cn.itcast.travel.service.impl.UserServiceImpl;
/**
* Servlet implementation class RegistUserServlet
*/
@WebServlet("/registUserServlet")
public class RegistUserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取前端的数据
Map<String, String[]> map=request.getParameterMap();
String code=request.getParameter("check"); //获取前台的验证码
HttpSession session=request.getSession();
String scode=(String) session.getAttribute("CHECKCODE_SERVER"); //获取来自生成验证码的session域
session.removeAttribute("CHECKCODE_SERVER"); //为了防止客户端倒退,避免前一个验证码继续有效,保证验证码只用一次
System.out.println(scode);
System.out.println(code);
//判断验证码是否正确
if(scode == null||!scode.equalsIgnoreCase(code)) {//如果不正确
ResultInfo info=new ResultInfo(); //返回的结果封装info对象
info.setErrorMsg("验证码错误!");
info.setFlag(false);
System.out.println("验证码错误");
//将info对象序列化成json
ObjectMapper oMapper=new ObjectMapper();
String json=oMapper.writeValueAsString(info);
//将json字符串回写到客户端
//设置content-type
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
return;
}
//2.封装对象
User user=new User();
try {
BeanUtils.populate(user, map); //将map中的字典封装成user
} catch (IllegalAccessException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(user);
//3.调用service层的函数来完成注册
UserService userService=new UserServiceImpl();
boolean flag=userService.regist(user);
ResultInfo info=new ResultInfo(); //返回的结果封装info对象
//4.响应结果
if(flag) { //注册成功
info.setFlag(true);
}
else { //注册失败
info.setErrorMsg("注册失败!");
info.setFlag(false);
System.out.println("注册失败");
}
//将info对象序列化成json
ObjectMapper oMapper=new ObjectMapper();
String json=oMapper.writeValueAsString(info);
//将json字符串回写到客户端
//设置content-type
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
}
}
After receiving the json data processed by the controller, the front end displays it
Front-end code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>注册</title>
<link rel="stylesheet" type="text/css" href="css/common.css">
<link rel="stylesheet" href="css/register.css">
<!--导入jquery-->
<script src="js/jquery-3.3.1.js"></script>
<script>
//校验用户名
function checkUsername() {
//1.获取用户名值
var username = $("#username").val();
//2.定义正则
var reg_username = /^\w{8,20}$/;
//3.判断,给出提示信息
var flag = reg_username.test(username);
if(flag){
//用户名合法
$("#username").css("border","");
}else{
//用户名非法,加一个红色边框
$("#username").css("border","3px solid red");
}
return flag;
}
//校验密码
function checkPassword() {
//1.获取用户名值
var password = $("#password").val();
//2.定义正则
var reg_password = /^\w{8,20}$/;
//3.判断,给出提示信息
var flag = reg_password.test(password);
if(flag){
//用户名合法
$("#password").css("border","");
}else{
//用户名非法,加一个红色边框
$("#password").css("border","3px solid red");
}
return flag;
}
//校验电子邮件
function checkEmail() {
//1.获取用户名值
var email = $("#email").val();
//2.定义正则
//对电子邮件的验证
var reg_email = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
//3.判断,给出提示信息
var flag = reg_email.test(email);
if(flag){
//用户名合法
$("#email").css("border","");
}else{
//用户名非法,加一个红色边框
$("#email").css("border","3px solid red");
}
return flag;
}
//检验姓名(中文)
function checkName() {
//1.获取姓名值
var name=$("#name").val();
//2.定义正则
//对姓名进行验证
var reg_name =/^[\u0391-\uFFE5]+$/;
//3.判断,给出提示信息
var flag = reg_name.test(name);
if(flag){
//用户名合法
$("#name").css("border","");
}else{
//用户名非法,加一个红色边框
$("#name").css("border","3px solid red");
}
return flag;
}
//检验手机号
function checkTelephone() {
//1.获取姓名值
var telephone=$("#telephone").val();
//2.定义正则
//对姓名进行验证
var reg_telephone =/^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;;
//3.判断,给出提示信息
var flag = reg_telephone.test(telephone);
if(flag&&(telephone.length==11)){
//手机号合法
$("#telephone").css("border","");
}else{
//手机号非法,加一个红色边框
$("#telephone").css("border","3px solid red");
}
return flag;
}
//检验出生日期
function checkBirthday() {
//1.获取出生日期
var birthday=$("#birthday").val();
var date1=birthday.replace(/-/g,"/");//替换字符,变成标准格式(检验格式为:'2009-12-10')
// var obj_value=obj.replace("-","/");//替换字符,变成标准格式(检验格式为:'2010-12-10 11:12')
var date1=new Date(Date.parse(date1));
print(date1)
var date2=new Date();//取今天的日期
//3.判断,给出提示信息
if(date1>date2){
//日期非法,加一个红色边框
$("#birthday").css("border","3px solid red");
return false;
}
else{
$("#birthday").css("border","");
return true;
}
}
//ajax校验
$(function() {
$("#registerForm").submit(function() {
//发送数据到服务器
if(checkUsername()&&checkPassword()){ //如果校验成功
//异步提交
$.post("registUserServlet",$(this).serialize(),function(data){ //date是服务器返回的值
//处理服务器响应的数据 data
if(data.flag){//如果返回的json的flag是true,注册成功,跳转页面
//注册成功,跳转页面
location.href="register_ok.html";
}
else{ //注册失败,给error_msg标签显示错误信息
$("#error_msg").html(data.errorMsg);
}
});
}
return false;
});
//当某一个组件失去焦点时,调用对应的校验方法
$("#username").blur(checkUsername);
$("#password").blur(checkPassword);
$("#email").blur(checkEmail);
$("#name").blur(checkName);
$("#telephone").blur(checkTelephone);
$("#birthday").blur(checkBirthday);
});
</script>
</head>
<body>
<!--引入头部-->
<div id="header"></div>
<!-- 头部 end -->
<div class="rg_layout">
<div class="rg_form clearfix">
<div class="rg_form_left">
<p>新用户注册</p>
<p>USER REGISTER</p>
</div>
<div class="rg_form_center">
<div id="error_msg" style="color: red; text-align:center;" ></div>
<!--注册表单-->
<form id="registerForm" action="user">
<!--提交处理请求的标识符-->
<input type="hidden" name="action" value="register">
<table style="margin-top: 25px;">
<tr>
<td class="td_left">
<label for="username">用户名</label>
</td>
<td class="td_right">
<input type="text" id="username" name="username" placeholder="请输入账号">
</td>
</tr>
<tr>
<td class="td_left">
<label for="password">密码</label>
</td>
<td class="td_right">
<input type="text" id="password" name="password" placeholder="请输入密码">
</td>
</tr>
<tr>
<td class="td_left">
<label for="email">Email</label>
</td>
<td class="td_right">
<input type="text" id="email" name="email" placeholder="请输入Email">
</td>
</tr>
<tr>
<td class="td_left">
<label for="name">姓名</label>
</td>
<td class="td_right">
<input type="text" id="name" name="name" placeholder="请输入真实姓名">
</td>
</tr>
<tr>
<td class="td_left">
<label for="telephone">手机号</label>
</td>
<td class="td_right">
<input type="text" id="telephone" name="telephone" placeholder="请输入您的手机号">
</td>
</tr>
<tr>
<td class="td_left">
<label for="sex">性别</label>
</td>
<td class="td_right gender">
<input type="radio" id="sex" name="sex" value="男" checked> 男
<input type="radio" name="sex" value="女"> 女
</td>
</tr>
<tr>
<td class="td_left">
<label for="birthday">出生日期</label>
</td>
<td class="td_right">
<input type="date" id="birthday" name="birthday" placeholder="年/月/日">
</td>
</tr>
<tr>
<td class="td_left">
<label for="check">验证码</label>
</td>
<td class="td_right check">
<input type="text" id="check" name="check" class="check">
<img src="checkCode" height="32px" alt="" onclick="changeCheckCode(this)">
<script type="text/javascript">
//图片点击事件
function changeCheckCode(img) {
img.src="checkCode?"+new Date().getTime();
}
</script>
</td>
</tr>
<tr>
<td class="td_left">
</td>
<td class="td_right check">
<input type="submit" class="submit" value="注册">
<span id="msg" style="color: red;"></span>
</td>
</tr>
</table>
</form>
</div>
<div class="rg_form_right">
<p>
已有账号?
<a href="#">立即登录</a>
</p>
</div>
</div>
</div>
<!--引入尾部-->
<div id="footer"></div>
<!--导入布局js,共享header和footer-->
<script type="text/javascript" src="js/include.js"></script>
</body>
</html>
Continue to analyze in the next article