一.导入初始化的maven项目
导入的方法可以参考下面链接:
如何在eclipse中导入maven项目 ?在eclipse中导入maven项目的教程-天极下载
如何用Eclipse导入一个已经存在的Maven项目 - 爱码爱生活
???Eclipse在运行 Maven项目build时出现No compiler is provided in this environment的处理_康冕峰的博客-CSDN博客
导入后并启动初始化的maven项目的静态页面
二.创建数据库
?
/*==============================================================*/
/* 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.1注册登录功能的开发
学习目标
? ? ?1.能够完成项目注册功能
? ? ?2.能够完成邮箱登录功能
学习指南
- 注册功能的表单校验
- 注册功能的验证码校验
- 注册功能的邮箱激活
- 登录功能的实现
3.1.1注册功能分析
1.前端页面功能实现?
? *使用js完成表单校验
? *使用ajax完成表单提交
? *注册成功后,跳转的页面success.html
1.1表单校验功能
? ? ?①用户名:单词字符,长度8-20位(当然这里也可以设计成校验是否中英文名字)
? ? ?②密码:单词字符,长度8-20位
? ? ?③email:邮件格式
? ? ?④姓名:非空
? ? ?⑤手机号:手机号格式
? ? ?⑥出生日期:非空
? ? ?⑦验证码:非空
1.2代码的编写
表单各种校验js代码可以参考:JS常用的表单验证(数字、长度,汉字,邮箱,手机号,身份证等)_无尽的沉默的博客-CSDN博客_js表单验证身份证
ajax是用来验证表单的正确性?
①用户名校验
用正则表达式校验账号密码是否符合规范
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;
}
②密码校验
//校验密码
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 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校验
//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.后端代码的编写
首先编写web层的控制器RegistUserServlet,它用来接收前端请求数据信息,然后交给service层处理
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);
}
}
service层中userservice接口和它的实现类userserviceImpl编写
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;
}
}
DAO层中userdao接口和它的实现类userdaoImpl编写
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()
);
}
}
至此注册这个功能原理基本完成
其他:
JDBCUtils类中编写了获得连接池对象的方法,这里不阐述
jdbc连接数据库的jar包以及js相关的jar包,这里省略了
3.后台验证码和前台对返回数据的处理
我们只需要在web层的控制器RegistUserServlet中编写接收来自客户端的验证码值和接收来自checkCodeServlet中session域值,然后两者进行比较,如果不相同,则设置结果对象信息为验证码错误,并将结果对象序列化为json,返回给客户端显示
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);
}
}
前端接收来自控制器处理的json数据后,进行显示
前端代码:
<!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>
下一篇接着继续分析?
|