技术选型
- web层
(1)Servlet:前端控制器
(2) html:视图
(3)Filter:过滤器
(4)BeanUtils:数据封装
(5)Jackson:json序列化工具
- Service层
(1) javamail:java发送邮件的工具
(2)Redis:nosql内存数据库
(3)jedis:java的Redis客户端
- Dao层
(1)Mysql:数据库
(2)Druid:数据库连接池
(3)jdbcTemple:jdbc的工具
创建数据库
---创建数据库
create database travel;
---使用数据库
user travel;
--创建表
赋值提高好的sql
注册功能的实现
- 功能实现的分析图
- 代码实现
(1)前端代码实现
(2)表单校验
//1.校验用户名
//单词字符,长度8到20位
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 red solid");
}
return flag;
}
//2.校验密码
//单词字符,长度8到20位
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","1px red solid");
}
return flag;
}
//校验邮箱
function checkEmail(){
//1.获取邮箱
var email=$("#email").val();
//2.定义正则
var reg_email=/^\w+@\w+\.\w+$/;
var flag = reg_email.test(email);
if (flag){
$("#email").css("border","");
}else {
$("#email").css("border","red 1px solid");
}
return flag;
}
$(function () {
//当表单提交时,调用所有的校验方法
$("#registerForm").submit(function(){
//1.发送数据到服务器
if(checkUsername() && checkPassword() && checkEmail()){
//校验通过,发送ajax请求,提交表单的数据 username=zhangsan&password=123
$.post("registUserServlet",$(this).serialize(),function(data){
//处理服务器响应的数据 data {flag:true,errorMsg:"注册失败"}
if(data.flag){
//注册成功,跳转成功页面
location.href="register_ok.html";
// alert("被执行?");
}else{
//注册失败,给errorMsg添加提示信息
$("#errorMsg").html(data.errorMsg);
}
});
}
//2.不让页面跳转
return false;
//如果这个方法没有返回值,或者返回为true,则表单提交,如果返回为false,则表单不提交
});
//当某一个组件失去焦点是,调用对应的校验方法
$("#username").blur(checkUsername);
$("#password").blur(checkPassword);
$("#email").blur(checkEmail);
});
(3)异步(ajax)提交表单
在此使用异步提交表单是为了获取服务器相应的数据,因为我们前台使用的HTML作为视图层,不能够直接从servlet相关的域对象获取值,只能通过ajax获取相应的数据
- 编写RegistUservlet
@WebServlet("/registUserServlet")
public class RegistUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//验证校验
String check = request.getParameter("check");
//从session中获取验证码
HttpSession session = request.getSession();
String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");
//为了保证验证码只能使用一次
session.removeAttribute("CHECKCODE_SERVER");
//比较
if (checkcode_server == null || !checkcode_server.equalsIgnoreCase(check)) {
//验证错误
ResultInfo info = new ResultInfo();
//注册失败
info.setFlag(false);
info.setErrorMsg("验证错误");
//将info对象序列化为json
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
return ;
}
//1.获取数据
Map<String, String[]> map = request.getParameterMap();
//2.封装对象
User user = new User();
try {
BeanUtils.populate(user, map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//调动service完成注册
UserService service = new UserServiceImpl();
boolean flag = service.regist(user);
ResultInfo info = new ResultInfo();
//4.响应结果
if (flag) {
//注册成功
info.setFlag(true);
} else {
//注册失败
info.setFlag(false);
info.setErrorMsg("注册失败!");
}
//将info对象序列化为json
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
//将json数据写回客户端
//设置content-type
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
}
- 编写UserService以及UserServiceImpl
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
@Override
//注册用户
public boolean regist(User user) {
//根据用户名查询用户对象
User u=userDao.findByUsername(user.getUsername());
if (u!=null){
/*用户名存在,注册失败*/
return false;
}
//2.保存用户信息
//2.1设置激活码,唯一字符串
user.setCode(UuidUtil.getUuid());
//2.2设置激活的状态
user.setStatus("N");
userDao.save(user);
//3.发送邮箱
//3.1编制发送的正文
String content="<a href='http://localhost/travel/activeUserServlet?code="+user.getCode()+"'>" +
"点击激活【黑马旅游网】" +
"</a>";
MailUtils.sendMail(user.getEmail(),content,"激活邮件");
return true;
}
- 编写userDao以及UserDaoImpl
public class UserDaoImpl implements UserDao {
private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public User findByUsername(String username) {
User user=null;
try {
//1.定义sql
String sql = "select * from tab_user where username = ?";
//2.执行sql
user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username);
} catch (Exception e) {
}
return user;
}
@Override
public void save(User user) {
//1.定义sql
String sql="insert into tab_user(username,password,name,birthday,sex,telephone,email,status,code)value(?,?,?,?,?,?,?,?,?)";
//执行sql
template.update(sql,user.getUsername(),
user.getPassword(),
user.getName(),
user.getBirthday(),
user.getSex(),
user.getTelephone(),
user.getEmail(),
user.getStatus(),
user.getCode()
);
}
邮件激活
-
为什么要进行邮件激活?为了保证用户填写的邮箱是正确的,将来可以推广一些宣传
-
信息,到用户的邮箱。
发送邮件
- 申请邮箱
- 开启授权吗(开启授权吗的方法访问百度)
- 邮件工具类:MailUtils,调用其中的sendMail方法可以完成邮件的发送
发送邮箱
//2.保存用户信息
//2.1设置激活码,唯一字符串
user.setCode(UuidUtil.getUuid());
//2.2设置激活的状态
user.setStatus("N");
userDao.save(user);
//3.发送邮箱
//3.1编制发送的正文
String content="<a href='http://localhost/travel/activeUserServlet?code="+user.getCode()+"'>" +
"点击激活【黑马旅游网】" +
"</a>";
MailUtils.sendMail(user.getEmail(),content,"激活邮件");
return true;
用户点击邮件激活
- 经过分析,发现,用户激活其实就是修改用户表中的status为“Y”
激活代码实现
- activeUserServlet
@WebServlet("/activeUserServlet")
public class ActiveUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取激活码
String code = request.getParameter("code");
if (code!=null){
//2.调用service完成激活
UserService service=new UserServiceImpl();
boolean flag=service.active(code);
//3.判断标记
String msg=null;
if (flag){
//激活成功
msg="激活成功,请<a href='login.html'>登录</a>";
}else {
//激活失败
msg="激活失败,请联系管理员!";
}
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(msg);
}
}
- userService:active
/*激活用户*/
@Override
public boolean active(String code) {
User user=userDao.findByCode(code);
if (user!=null){
//调用dao的修改激活状态的方法
userDao.updateStatus(user);
return true;
}else {
return false;
}
}
- userDao:findByCode updateSatus
@Override
public User findByCode(String code) {
User user=null;
try {
String sql="select * from tab_user where code=?";
user=template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),code);
}catch (DataAccessException e){
e.printStackTrace();
}
return user;
}
@Override
public void updateStatus(User user) {
String sql="update tab_user set status='Y' where uid =?";
template.update(sql,user.getUid());
}
登录功能的实现
代码实现
- 前台代码的实现
<script>
$(function () {
//1.给登录按钮绑定点击事件
$("#btn_sub").click(function () {
//2.发送ajax请求,提交表单数据
$.post("loginServlet",$("#loginForm").serialize(),function (data) {
if (data.flag){
//登录成功
location.href="index.html";
}else {
$("#errorMsg").html(data.errorMsg);
}
})
})
})
</script>
-
后台代码的实现
-
LoginServlet
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取用户名和密码数据
Map<String, String[]> map = request.getParameterMap();
//2.封装为user
User user = new User();
try {
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//调用service查询
UserService service=new UserServiceImpl();
User u=service.login(user);
ResultInfo info = new ResultInfo();
//4.判断用户对象是否为null
if (u==null){
//用户名或者密码错误
info.setFlag(false);
info.setErrorMsg("用户名或密码错误");
}
//5.判断用户是否激活
if (u!=null&& !"Y".equals(u.getStatus())){
//用户尚未激活
info.setFlag(false);
info.setErrorMsg("您尚未激活,请激活");
}
//6.判断登录成功
if (u!=null&& "Y".equals(u.getStatus())){
//登录成功
request.getSession().setAttribute("user",u);
info.setFlag(true);
}
//响应数据
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
- userService
@Override
public User login(User user) {
return userDao.findByUsernameAndPassword(user.getUsername(),user.getPassword()) ;
}
- UserDao
@Override
public User findByUsernameAndPassword(String username, String password) {
User user = null;
try {
//1.定义sql
String sql = "select * from tab_user where username = ? and password = ?";
//2.执行sql
user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username,password);
} catch (Exception e) {
}
return user;
}
index页面中用户姓名的提示信息功能
- header.html代码
<script>
$(function () {
$.get("findUserServlet",{},function (data) {
var msg="欢迎回来,"+data.name;
$("#span_username").html(msg);
});
});
</script>
- sevlet代码
@WebServlet("/findUserServlet")
public class FindUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.从session中获取登录用户的用户名
Object user = request.getSession().getAttribute("user");
//将user写回客户端
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json;charset=utf-8");
mapper.writeValue(response.getOutputStream(),user);
}
退出功能的实现
- 什么叫做登录?session中有user对象
- 实现步骤:
- 1.访问servlet,将session销毁
- 2.跳转到登录页面
代码实现
- header.html
- servlet:
@WebServlet("/exitServlet")
public class ExitServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.销毁session
request.getSession().invalidate();
//2.跳转登录页面
response.sendRedirect(request.getContextPath()+"/login.html");
}