赞
踩
目录
前言
JavaWeb学了有一段时间了,学到了很多东西,但学归学,它是不是真正成为自己的了还真不好说。俗话说得好,如果你能用自己的语言给别人把一个晦涩难懂的东西讲清楚,那你就真的会了。故作此文,教大家搭建一个非常基础的登录系统,顺便巩固一下这段时间学的重要知识。
一.项目需求和分析
1. 编写login.html登录页面:username $ password 两个输入框
2. 使用Druid数据库连接池技术,操作mysql,db1数据库中user表
3. 使用JdbcTemplate技术封装JDBC
4. 登录成功跳转到SuccessServlet展示:登录成功,username,欢迎你
5. 登录失败跳转到FailServlet展示:登录失败,用户名或密码错误
二. 准备工作资源
* idea企业版(因为企业版才集成的有Tomcat服务器)
* 各种依赖jar包和驱动:
链接:https://pan.baidu.com/s/1fKEaSDFllKVUR-QasSgA5g 提取码:lx4o
* Mysql5.7:Mysql 8可能会遇到一些问题,版本不一样有些规则会修改,所以尽量按我的环境来,我都踩过这些坑
* jdk1.8或以上:如果提示有无效版本,你可以换高版本的jdk,我还有个jdk14换着用的
* Navicat for Mysql:根据自己喜好,可有可无,也可以用其他的可视化数据库操作软件
选择new->Module->Java Enterprise.
配置如下:只需要改这三项 :
JavaEE version改成Java EE 7
勾选Web Application,
取消Create web.xml的勾选就可以了,其他不用管,Next
位置仅供参考
创建完成后先在web文件夹下创建俩文件夹用来存储依赖jar包和驱动包
这些依赖包并不能直接使用,我们要右键点击lib文件夹,或者我们把这些包全部选中再右键,然后add as library->Level选Module Library,这样这些jar包就生效了。啥,不知道add as library是啥东西,点右边吧 ——> 传送门,带你飞~
根据需求分析我们了db1数据库并创建user表,我添加了一条数据用于后面验证demo是否成功。
为了使用 druid数据库连接池技术 来操作数据库,我们引入druid.properties来配置数据库,放在src目录下即可。
(链接:https://pan.baidu.com/s/14gU_aEYped66A0wm_P4zJQ 提取码:v0se)
准备工作搞定~
三. 编写逻辑代码
明人不说暗话,咱也不会,咋也不整那么多花里胡哨的,有那个意思就行了。
放到web目录下
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Login</title>
- </head>
- <body>
- <!-- action指定的路径为:虚拟目录+资源路径-->
- <form action="/login_demo2/loginServlet" method="post">
- 用户名:<input type="text" name="username"><br>
- 密码:<input type="password" name="password"><br>
-
- <input type="submit" value="登录">
- </form>
- </body>
- </html>
这里面装的都是用户的各个属性。为啥要这样写呢?单独把用户封装起来,然后用户操作数据库等操作单独写接口,这样才能高内聚,低耦合的效果。
放到src.cn.it.np.domain目录下(给你个完整项目路径,你看看就知道了)
- package cn.it.np.domain;
-
- /**
- * 用户的实体类(JavaBean)
- */
- public class User {
- //用户id
- private int id;
- //用户名
- private String username;
- //密码
- private String password;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- @Override
- public String toString() {
- return "User{" +
- "id=" + id +
- ", username='" + username + '\'' +
- ", password='" + password + '\'' +
- '}';
- }
- }
由于用到了Druid和Template,为了封装和简化Mysql的操作,我们一般都会编写一个JDBC工具类,让我们更方便的获取连接池对象或Connection对象 ,用到了Druid的知识。
什么?你说你不知道什么叫Druid!点右边带你坐飞机 ——> 带你装b,带你飞
放到src.cn.it.np.util目录下
- package cn.it.np.util;
-
- import com.alibaba.druid.pool.DruidDataSourceFactory;
-
- import javax.sql.DataSource;
- import java.io.IOException;
- import java.io.InputStream;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.util.Properties;
-
- /**
- * JDBC工具类 使用Druid
- */
- public class JDBCUtils {
-
- private static DataSource ds;
-
- static {
- try {
- //1.加载配置文件
- Properties pro = new Properties();
- //使用ClassLoader加载配置文件,获取字节输入流
- InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
- pro.load(is);
-
- //2.初始化连接池对象
- ds = DruidDataSourceFactory.createDataSource(pro);
-
- } catch (IOException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-
- //获取连接池对象
- public static DataSource getDataSource(){
- return ds;
- }
-
- //获取连接Connection对象
- public static Connection getConnection() throws SQLException {
- return ds.getConnection();
- }
- }
百度Dao如下:
DAO(Data Access Object)是一个数据访问接口,数据访问:顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。
它负责和数据库打交道,我们通过它来将用户实体类User和数据库连接起来实现判断用户账号密码是否在数据库中的操作。这里主要用到了Spring框架里的 JdbcTemplate,同时还用到了工具类JDBCUtils。什么?你说你不知道Template?快点击这里吧!——> 带你飞
放到src.cn.it.np.dao目录下
- package cn.it.np.dao;
-
- import cn.it.np.domain.User;
- import cn.it.np.util.JDBCUtils;
- import org.springframework.dao.DataAccessException;
- import org.springframework.jdbc.core.BeanPropertyRowMapper;
- import org.springframework.jdbc.core.JdbcTemplate;
-
- /**
- * 操作数据库中User表的类
- */
- public class UserDao {
- //声明JDBCTemplate对象共用
- private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
-
- /**
- * 登录方法
- * @param loginUser 只有用户名和密码
- * @return user包含用户所有信息
- */
- public User login(User loginUser){
- try {
- //1.编写sql
- String sql = "select * from user where username = ? and password = ?";
-
- //2.调用template的query方法
- // User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), loginUser.getUsername(), loginUser.getPassword());
- User user = template.queryForObject(sql,
- new BeanPropertyRowMapper<User>(User.class), loginUser.getUsername(), loginUser.getPassword());
-
- return user;
- } catch (DataAccessException e) {
- e.printStackTrace();
- return null;
- }
- }
- }
判断用户是否成功登陆及后续的跳转操作,用到了Servlet的请求与转发操作。
啥?你说你不知道?快飞吧 ——> 好,你飞了
- package web.servlet;
-
- import cn.it.np.dao.UserDao;
- import cn.it.np.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("/loginServlet")
- public class loginServlet extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //1.设置字符编码
- req.setCharacterEncoding("utf-8");
- //2.接收user数据
- String username = req.getParameter("username");
- String password = req.getParameter("password");
-
- //3.封装成User对象
- User loginuser = new User();
- loginuser.setUsername(username);
- loginuser.setPassword(password);
-
- //4.判断与转发
- UserDao dao = new UserDao();
- User user = dao.login(loginuser);
-
- if(user != null){
- //登录成功
- //存储共享数据
- req.setAttribute("user",user);
- req.getRequestDispatcher("/successServlet").forward(req,resp);
- }else{
- //登录失败
- req.getRequestDispatcher("/failServlet").forward(req,resp);
- }
-
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- this.doGet(req,resp);
- }
- }
- package web.servlet;
-
- import cn.it.np.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("/successServlet")
- public class successServlet extends HttpServlet {
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request,response);
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //1.获取request域中共享的user数据
- User user = (User)request.getAttribute("user");
-
- //2.页面打印
- response.setContentType("text/html;charset=utf-8");
- response.getWriter().write("欢迎" + user.getUsername() + "登录成功!");
- }
- }
- package 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("/failServlet")
- public class failServlet extends HttpServlet {
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doGet(request,response);
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- //页面打印
- response.setContentType("text/html;charset=utf-8");
- response.getWriter().write("登录失败");
- }
- }
只要在要检测部分前面加上注解 @Test 即可(说到这里可能有些小小白会无法运行,那肯定是你没有导包。idea很智能,点一下注解,alt+enter键回车就能自动导包了)
- package cn.it.np.test;
-
- import cn.it.np.dao.UserDao;
- import cn.it.np.domain.User;
- import org.junit.Test;
-
-
- public class UserDao_Test {
- @Test
- public void testLogin(){
- User loginuser = new User();
- loginuser.setUsername("zhangsan");
- loginuser.setPassword("666");
-
- UserDao dao = new UserDao();
- User user = dao.login(loginuser);
- System.out.println(user);
- }
- }
然后点击左侧的播放按钮,如果成功输出user信息则说明UserDao模块是ok的。
至此,项目基本完成,看看能不能运行吧!
四. 测试及运行
五. 反思总结
通过本次项目的学习和演示,我总结出以下一个登陆模块编写流程:
前端界面(login.html)-> 用户实体类(User)-> 数据库接口类(UserDao) -> 中间可穿插单元测试类(UserDao_Test等测试类) -> 用到什么工具类就写什么工具类(JDBCUtils)-> 逻辑类(按业务逻辑写完剩下的常规类)
经过多次bug的折磨,我明白要经常进行unit测试,要养成好习惯,希望大家能一起进步,成为大牛牛!
和之前的代码不完全一致,是重新写的,要注意的是这里没用UserDao写全,为了快速搭建我就写死了。你们需要可以用UserDao接口,方法和上面是一样的new User对象来接收。用了jsp简化书写,加入验证码验证功能。
- package cn.it.np;
-
- import javax.imageio.ImageIO;
- 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.awt.*;
- import java.awt.image.BufferedImage;
- import java.io.IOException;
- import java.util.Random;
-
- @WebServlet("/checkCodeServlet")
- public class checkCodeServlet extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //1.定义图片宽高
- int width = 100;
- int height = 50;
-
- //2.创建一个对象,在内存中存图片
- BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
-
- //3.美化图片,掏出画笔开始搞
- Graphics g = image.getGraphics();
-
- //4.先给图片填个色
- g.setColor(Color.orange);
- g.fillRect(0,0,width,height);
-
- //5.在图片的边缘画一画使图片效果更好
- g.setColor(Color.blue);
- g.drawRect(0,0,width-1,height-1);
-
- //7.制造干扰条纹
- Random ran = new Random();
- g.setColor(Color.gray);
- for(int i=0;i<8;i++){
- int x1 = ran.nextInt(width);
- int x2 = ran.nextInt(width);
- int y1 = ran.nextInt(height);
- int y2 = ran.nextInt(height);
- g.drawLine(x1,y1,x2,y2);
- }
-
- //6.画验证码字符
- StringBuilder sb = new StringBuilder();
- g.setColor(Color.black);
- String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-
- for(int i=1;i<=4;i++){
- //创造不超过str长度的随机下标
- int index = ran.nextInt(str.length());
- //获得该随机下标对应的字符
- char ch = str.charAt(index);
- sb.append(ch);
- //在适当的位置画字符
- g.drawString(ch + "",width/5*i,height/2);
- }
- //用session存储验证码字符
- String str_checkCode = sb.toString();
- HttpSession session = req.getSession();
- session.setAttribute("checkCode",str_checkCode);
-
- //将图片输出到屏幕上
- ImageIO.write(image,"jpg",resp.getOutputStream());
-
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- this.doGet(req,resp);
- }
- }
- package cn.it.np;
-
- import javax.imageio.ImageIO;
- import javax.servlet.RequestDispatcher;
- import javax.servlet.ServletContext;
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.*;
- import java.awt.*;
- import java.awt.image.BufferedImage;
- import java.io.IOException;
- import java.util.Random;
-
- @WebServlet("/loginServlet")
- public class loginServlet extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //1.获取表单参数
- String username = req.getParameter("username");
- String password = req.getParameter("password");
- String checkCode = req.getParameter("checkCode");
-
- //2.判断验证码和密码是否正确
- //获取验证码
- HttpSession session = req.getSession();
- String str_checkCode =(String) session.getAttribute("checkCode");
- //删除session中存储的验证码
- session.removeAttribute("checkCode");
-
- //验证码正确,判断账号密码是否正确
- if(str_checkCode != null && checkCode.equalsIgnoreCase(str_checkCode)){
- //账号密码也正确
- if(username.equals("zhangsan") && password.equals("666")){//使用UserDao接口
- //用session存储用户信息并转发到success.jsp页面
- session.setAttribute("username",username);
- resp.sendRedirect(req.getContextPath() + "/success.jsp");
- }else{
- //账号密码不正确
- req.setAttribute("fail","用户名或密码错误!");
- req.getRequestDispatcher(req.getContextPath() + "/login.jsp").forward(req,resp);
-
- }
- }else{
- //验证码不正确,跳转到login.jsp,提示验证码错误
- req.setAttribute("codeFail","验证码错误!");
- req.getRequestDispatcher(req.getContextPath() + "/login.jsp").forward(req,resp);
- }
-
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- this.doGet(req,resp);
- }
- }
- <%@ page import="java.awt.image.BufferedImage" %>
- <%@ page import="java.awt.*" %>
- <%@ page import="java.util.Random" %>
- <%@ page import="javax.imageio.ImageIO" %>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>login</title>
- <script>
- window.onload = function (ev) {
- document.getElementById("checkCode").onclick = function (ev1) {
- this.src = "/checkCodeServlet?time=" + new Date().getTime();
- }
-
- }
- </script>
-
- <style>
- div{
- color: red;
- }
- </style>
- </head>
- <body>
- <form action="/loginServlet" method="post">
- <table>
- <tr>
- <td>用户名</td>
- <td><input type="text" name="username"></td>
- </tr>
-
-
- <tr>
- <td>密码</td>
- <td><input type="password" name="password"></td>
- </tr>
-
- <tr>
- <td>验证码</td>
- <td><input type="text" name="checkCode"></td>
- </tr>
-
- <tr>
- <td colspan="2"><img src="/checkCodeServlet" id="checkCode"></td>
- </tr>
-
- <tr>
- <td colspan="2">
- <input type="submit" value="登录">
- </td>
- </tr>
-
- </table>
- </form>
-
- <div><%=request.getAttribute("fail") == null ? "" : request.getAttribute("fail")%></div>
- <div><%=request.getAttribute("codeFail") == null ? "" : request.getAttribute("codeFail")%></div>
-
- </body>
- </html>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>success</title>
- </head>
- <body>
- <h1>欢迎你,<%=request.getSession().getAttribute("username")%>
- </body></h1>
-
- </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。