文章目录

  • 登录功能分析图解
  • 最终实现截图
  • 实现登录功能
    • 1. 创建测试类
    • 2. 创建业务层UserService
    • 3. 创建实体类 - User用户类和Msg错误提示类
    • 4. 创建dao层
    • 5. 创建dao的映射文件
    • 6. 创建属性文件,连接数据库db.properties
    • 7. 编写日志配置log4j2.xml
    • 8. 配置Spring核心配置文件applicationContext.xml
    • 9. 创建获取class类的工具类GetDaoUtils
    • 10. 运行测试类,测试逻辑是否有问题
    • 11. 编写随机生成验证码的业务逻辑类
    • 12. 编写图片验证码的servlet
    • 13. 登录servlet
    • 14. 编写filter,全局编码解决
    • 15. 编写页面jsp,点击验证码进行图片更换
    • 16. aJax实现异步登录,并判断输入是否合法,防止非法注入
    • 17. 运行结果

登录功能分析图解

最终实现截图

实现登录功能

1. 创建测试类

//测试user业务层
public class TestUserService {//测试登录@Testpublic void test01(){UserService userService = new UserService();//创建user数据User user = new User();user.setUsername("861221293");user.setPassword("ABC123456");//user.setStatus("Y");//用户激活//测试登录int code = userService.login(user);if(code == 1){System.out.println("登录成功");}else if(code == -1){System.out.println("用户名或密码错误");}else if(code == -2){System.out.println("用户未激活");}}
}

2. 创建业务层UserService

//user业务层
public class UserService {private static UserDao userDao = null;//登录用户public int login(User user) {userDao = GetDaoUtils.getMapper(UserDao.class);User u = userDao.getUserByUsernamePassword(user);if(u == null){return -1;  //账号密码匹配找不到}else {//判断用户user是否激活if(u.getStatus().equals("Y")){return 1;   //账号密码正确,且已经激活}else {return -2;  //账号未激活}}}
}

3. 创建实体类 - User用户类和Msg错误提示类

//User类
public class User {private int uid;private String username;    //登录用户名private String password;    //密码private Date birthday;      //生日private String name;        //昵称private String sex;         //性别private String telephone;   //电话号码private String email;       //邮箱private String status;      //激活状态private String code;        //激活码(UUID)//省略getter/setter方法
}//Msg信息提示类
public class Msg {private int code;private Object data;//省略getter/setter方法
}

4. 创建dao层

public interface UserDao {// 通过usernmae和password查询用户public User getUserByUsernamePassword(User user);
}

5. 创建dao的映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.xgf.dao.UserDao"><select id="getUserByUsernamePassword" parameterType="com.xgf.bean.User" resultType="com.xgf.bean.User">select uid,username,password,name,birthday,sex,telephone,email,status,codefrom tab_userwhere username = #{username} and password = #{password}</select>
</mapper>

6. 创建属性文件,连接数据库db.properties

#mysql jdbc 属性文件里面不能有分号
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/travelnetwork?useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.username = root
jdbc.password = 861221293

7. 编写日志配置log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志文件 -->
<Configuration status="WARN"><Appenders><!--Console向控制台追加日志 SYSTEM_OUT系统输出控制台  --><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="      日志log:    %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n "/></Console></Appenders><!-- 记录哪些类的日志信息  --><Loggers><!--DEBUG 是日志级别 调试信息也会记录 --><Logger name="com.xgf.dao" level="DEBUG"/><Root level="error"><AppenderRef ref="Console"/></Root></Loggers>
</Configuration>

8. 配置Spring核心配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mybatis="http://mybatis.org/schema/mybatis-spring" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!--1. 引入jdbc的属性文件,在配置中通过占位使用 --><context:property-placeholder location="classpath*:db.properties" /><!--2. <context:component-scan>扫描包中注解所标注的类(@Component、@Service、@Controller、@Repository) --><context:component-scan base-package="com.xgf"/><!--3. 由spring管理    配置数据源数据库连接(从jdbc属性文件中读取参数) --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><property name="url" value="${jdbc.url}"/><property name="driverClassName" value="${jdbc.driver}"/></bean><!--  通过spring来管理Mybatis的sqlSessionFactory对象创建,将MyBatis的二级缓存配置configLocation粘入  --><!--4. 通过完全限定名匹配查找  创建SqlSessionFactoryBean  --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /></bean><!-- 5. mybatis提供的一个注解扫描标签(搜索映射器 Mapper 接口),通过自动扫描注解的机制,创建每个dao接口定义的bean  --><mybatis:scan base-package="com.xgf.dao"/></beans>

9. 创建获取class类的工具类GetDaoUtils

// 获取bean工具类
public class GetDaoUtils {private static ApplicationContext applicationContext = null;//静态代码块 只加载一次static {//加载配置文件applicationContext = new ClassPathXmlApplicationContext("com/xgf/config/applicationContext.xml");}public static <T> T getMapper(Class classFile) {return (T) applicationContext.getBean(classFile);}
}

10. 运行测试类,测试逻辑是否有问题

测试结果,测试成功

11. 编写随机生成验证码的业务逻辑类


/*
* 生成验证码,并将验证码转化为图片的业务层
* */
public class VerificationCodeService {public VerificationCodeService() {}// 生成验证码字符串 -- 随机数public String createRandomCode() {String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";//所有随机数字符串集合//Random类 产生指定范围内的随机数Random random = new Random();StringBuilder sb = new StringBuilder();//随机截取4个字符for(int i =0 ;i < 4; i++){//4个随机数//包括开头不包括结尾 从0到str.length()-1里面随机产生一个整数int index = random.nextInt(str.length());//从0到str.length()不包括最后一个 右边开区间char randomStr = str.charAt(index);//安装随机产生的值获取字符sb.append(randomStr);//StringBuilder拼接字符串}return sb.toString();}//  将生成的随机字符串验证码转化为图片public BufferedImage changeStringToImage(String code) {Random rd = new Random();//创建一个画布int width = 80;int height = 30;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//创建画笔Graphics g = image.getGraphics();//给画笔设置颜色(绘制随机验证码的时候的验证码颜色)g.setColor(new Color(240,240,240));  //#00000   FFFFFF//设置验证码的 背景色g.fillRect(0, 0, width, height);// 设置字体g.setFont(new Font("宋体",Font.BOLD,16));g.setColor(new Color(0,0,0));  //#00000   FFFFFF// g.drawString(checkCodeStr, 20, 20);for (int i = 0; i <4 ; i++) {//画字符g.setColor(new Color(rd.nextInt(120),rd.nextInt(120),rd.nextInt(120)));g.drawString(code.charAt(i)+"", 16*i + rd.nextInt(16), 15 + rd.nextInt(10) );if(i % 2 == 0) {//画线g.setColor(new Color(rd.nextInt(120), rd.nextInt(120), rd.nextInt(120)));g.drawLine(rd.nextInt(75), rd.nextInt(28), rd.nextInt(75), rd.nextInt(28));}}return image;}
}

12. 编写图片验证码的servlet


//  验证码-生成验证码显示成图片的servlet
@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//服务器通知浏览器不要缓存response.setHeader("pragma","no-cache");response.setHeader("cache-control","no-cache");response.setHeader("expires","0");//1:创建一个验证码的业务VerificationCodeService vcs = new VerificationCodeService();//2:生产一个随机的4个字符组成的字符串String verificationCode =  vcs.createRandomCode();System.out.println(verificationCode);//将验证码保存到session中HttpSession session = request.getSession();session.setAttribute("verificationCode",verificationCode);//        request.setAttribute("verificationCode",verificationCode);//3:将字符串转成图片//BufferedImage类将图片生成到内存中,然后直接发送给浏览器BufferedImage image =  vcs.changeStringToImage(verificationCode);//4:使用OutputStream写到浏览器
//        System.out.println(image);//获取输出流ServletOutputStream outputStream = response.getOutputStream();ImageIO.write(image,"jpeg",outputStream);//参1,内存中的图片  参2,格式  参3,字节输出流outputStream.flush();outputStream.close();//关流
//        request.getRequestDispatcher("/").forward(request,response);}
}

13. 登录servlet

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {UserService userService = new UserService();HttpSession session = request.getSession();//获取session对象,里面主要是验证码和当前userMsg msg = new Msg();//提示信息//用户输入的验证码String inputCheckCode = request.getParameter("inputCheckCode");//从session中获取系统当前生成的验证码String verificationCode = (String) session.getAttribute("verificationCode");System.out.println("inputCheckCode : " + inputCheckCode + " ;\t verificationCode : " + verificationCode);//inputCheckCode 与 verificationCode//相同表示验证码不正确,将提示信息写到页面的错误提示if (inputCheckCode == null || !inputCheckCode.equalsIgnoreCase(verificationCode)) {//验证码不看大小写msg.setCode(-3);msg.setData("验证码输入出错,请重新输入验证码");//将字符串转换为json数据格式返回给浏览器String json = new ObjectMapper().writeValueAsString(msg);response.getWriter().println(json);return; //返回不继续执行}//获取请求参数Map<String, String[]> map = request.getParameterMap();//当前登录用户User loginUser = new User();try {//参1 javaBean 参2 map 封装bean对象BeanUtils.populate(loginUser, map);//将map里面所有的参数赋值给javaBean(login就是输入的username和password)} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}//调用service处理参数,查询当前登录username和password是否存在int code = userService.login(loginUser);//响应给浏览器 ajax 是响应json给浏览器就可以msg.setCode(code);//设置codeif (code == 1) {msg.setData("登录成功,欢迎您的使用Login Success");//将登录user保存到session中session.setAttribute("user", loginUser);//判断是否开启免登陆//登录成功且开启了十天免登陆  就要保存/覆盖cookieString ssh = request.getParameter("ssh");//从session中删除生成的验证码 不移除的话可能会覆盖新的验证码session.removeAttribute("verificationCode");} else if (code == -1) {msg.setData("您输入的用户名或密码错误,请重新输入Incorrect user name or password");} else if (code == -2) {msg.setData("您的账号还没有激活,请前往激活The account is activated");}//将字符串转成json数据格式,返回给浏览器显示提示信息msgString json = new ObjectMapper().writeValueAsString(msg);response.getWriter().println(json);}
}

14. 编写filter,全局编码解决

//解决全站乱码问题,处理所有的请求,拦截所有设置编码
@WebFilter("/*")
public class CharchaterFilter implements Filter {public void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {System.out.println("CharchaterFilter");//设置请求编码req.setCharacterEncoding("UTF-8");//设置响应编码resp.setContentType("text/html;charset=UTF-8");//放行chain.doFilter(req, resp);}public void destroy() {}
}

15. 编写页面jsp,点击验证码进行图片更换

<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="data: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 id="username" name="username" type="text" placeholder="请输入账号"><input id="password" name="password" type="password" placeholder="请输入密码" autocomplete="off"><div class="verify"><input name="inputCheckCode" type="text" placeholder="请输入验证码" autocomplete="off"><span><img src="checkCodeServlet" alt="" onclick="changeCheckCode(this)"></span><script type="text/javascript">//图片点击事件function changeCheckCode(img) {img.src="checkCodeServlet?"+new Date().getTime();//添加时间戳}</script></div><div class="submit_btn" ><button id="btn_login" type="button">登录</button><div class="auto_login"><%-- ssh : 免密码登录 --%><input type="checkbox" name="ssh" value="ssh" class="checkbox" style="margin-left: 10px"><span >十天免登陆</span></div></div></form><div class="reg" >没有账户?<a href="javascript:;">立即注册</a></div></div></div>
</section>
<!--引入尾部-->
<div id="footer"></div>

16. aJax实现异步登录,并判断输入是否合法,防止非法注入

<script type="text/javascript" >//检查用户名是否规范function checkUserName(){//获取输入框的值var username = $("#username").val();//正则表达式  定义一个规则,执行test方法,符合规则返回true,否则返回falsevar reg =  /^\w{8,20}$/ ;var flag = reg.test(username); //判断//如果符合要求,设置输入框边框是正常,否则设置红色if(flag){$("#username").css("border","");}else{$("#username").css("border","1px solid red");}//alert(flag)return flag;}//检查密码是否规范function checkPassword(){//判断密码输入框的值是否合法var username = $("#password").val();var reg =  /^\w{8,20}$/ ;var flag = reg.test(username); //判断if(flag){$("#password").css("border","");//无色框}else{$("#password").css("border","1px solid red");//红框}//alert(flag)return flag;}//页面加载执行函数$(function () {$("#errorMsg").html("");// 判断两个输入框架的是否格式正确$("#username").blur(checkUserName);//输入框失去焦点// 如果正确,使用ajax发送请求到servlet$("#password").blur(checkPassword);//登录判断,username、password是否符合注册规范,如果不符合报错(防止直接注入)$("#btn_login").click(function () {//alert("点击btn_login")//要求两个值正确,我们才做提交if(checkUserName()&&checkPassword()){var username = $("#username").val()var password = $("#password").val()var inputCheckCode = $("#inputCheckCode").val()//alert(username+password+inputCheckCode)//写提交$.ajax({url:"LoginServlet",async:true,data:$("#loginForm").serialize(),type:"post",dataType:"json",success:function (data) {// alert(data)  {"code":1,"data":"登录成功"}if(1 == data.code){//跳转到主页 index.jsp$("#errorMsg").html("");window.location="index.jsp"}else{//显示在界面上$("#errorMsg").html(data.data);}},error:function () {alert("服务器发生了错误Error")//比如找不到servlet}});}else{$("#errorMsg").html("用户名或密码输入不规范,用户名密码错误");}})})</script>

17. 运行结果




登录成功:

【途牛旅游项目】02 - 登录功能实现 - 验证码功能 - ajax实现登录相关推荐

  1. 途牛旅游项目--登录带验证码

    学习目标 (1)改进登录 (2)注册功能 MySessionUtils改进 (1) A依赖B,移除B,A报错,耦合 com\wzx\util\MySessionUtils2.java public s ...

  2. 【途牛旅游项目】项目环境搭建,实现登陆功能

    项目准备 熟悉静态页面 查看真实在线的途牛旅游项目 其实也是一个商城而已,重点项目搭建,核心模块:登录 前言 (1)前言 为了巩固web基础知识,提升综合运用能力,故而讲解此案例. 要求,每位同学能够 ...

  3. 途牛旅游项目环境搭建

    途牛旅游项目环境搭建 准备工作 项目演示 熟悉静态页面 查看真实在线的途牛旅游项目 其实也是一个商城而已 重点项目搭建,核心模块:登录 准备工作 三层架构 (1)三层架构 (2)目录结构: 准备工作 ...

  4. 【途牛旅游项目】01 - 项目环境准备,实现登录功能

    文章目录 模仿途牛旅游网站的一个项目 项目初始化,目录结构 导入pom.xml依赖 创建数据库 模仿途牛旅游网站的一个项目 途牛地址:https://www.tuniu.com 项目初始化,目录结构 ...

  5. 途牛旅游项目—注册篇

    注册功能_功能分析 注册的后台功能代码 编写UserService的register方法测试 @Testpublic void test03() {UserService userService = ...

  6. 途牛旅游项目——注册邮箱激活

    UUID介绍 (1)什么是uuid 全球唯一的,不会重复的 固定长度的随机字符串 25fd9bcf50ad4dc39aa38f084d1801c8 (2)复制UUI工具类 com\wzx\util\U ...

  7. 【途牛旅游项目】03 - 注册功能实现(aJax提交,正则表达式判断,BeanUtils封装和注册转换器)

    文章目录 注册功能分析图解 实现样式截图 实现注册功能 1. 创建注册业务的测试方法 2. 创建业务层UserService的注册方法 3. 创建dao层接口方法 4. 创建dao的映射文件xml 5 ...

  8. 途牛旅游项目练习-登录篇

    项目准备工作 三层架构 准备工作 技术选型 (1)Web层 a)Servlet:前端控制器 b)html:视图 c)Filter:过滤器 d)BeanUtils:数据封装 e)Jackson:json ...

  9. 途牛旅游项目——注册功能_功能分析

    注册的后台功能代码 编写UserService的register方法测试 com\wzx\service\TestUserService.java @Testpublic void test03() ...

最新文章

  1. 浏览器兼容:IE6,IE7,IE8,FIREFOX,Chrome
  2. float与double的范围和精度
  3. mongo-yum安装-配置用户权限
  4. Spread表格组件For JAVA功能介绍—表格相关操作
  5. java utf 8 转unicode_java 在Unicode和UTF-8之间转换
  6. 【flink】flink 报错 key group from 44 to 45 does not contain 4
  7. vbs中的WScript.Network[属性与方法]
  8. fluent并行 linux_fluent并行计算命令
  9. 怎么用SQL sever打开mdf
  10. 学习心得《稻盛和夫经营学》的读后感2300字
  11. c语言健康指数,C-AHI——中国汽车健康指数
  12. IPv6改造的重要性
  13. javaWeb-第一版
  14. 通用 Mapper @KeySql 注解 genId 方法详解
  15. linux下网卡测速,Linux下 网卡测速
  16. Java的就业前景是怎么样啊 ?
  17. 汽车常识全面介绍 - 传动系统
  18. 设计模式之简单单例设计模式
  19. common conj
  20. Bootstrap--简易上手

热门文章

  1. Redux 使用教程
  2. PHP判断几天是某月的上旬、中旬或下旬
  3. AIUI的技能工作室使用
  4. macOS BigSur正式版来了!这些新变化和新功能值得一试
  5. 工作中任务安排合理的重要性和任务安排
  6. Acsl竞赛要考哪种计算机语言,美国计算机奥赛(ACSL)开始纳新
  7. 整理与总结:琼斯矢量和琼斯矩阵
  8. 电销机器人价格_电话电销机器人价格如何?会很贵吗?
  9. <爆>2022中文版-《海外博士申请指南-材料准备、时间线、套磁、面试及录取》免费分享
  10. 分享一下CFA一、二、三级学习经验