需求:实现一个像这样的简易登录功能,需要从数据库中判断输入的用户名和密码是否正确,正确返回一个登录成功的页面,错误返回失败页面
废话不多说,Let’s begin!
算法原理
从网页上传入一个username和一个password,在数据库中查看是否对应,并将结果放在一个user对象中,如果user为空(null)则说明没有找到对应数据,返回false,前端返回登录失败,如果不会空则返回true,前端返回登陆成功。
数据库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| SET NAMES utf8; SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `tb_user`; CREATE TABLE `tb_user` ( `id` int(50) NOT NULL AUTO_INCREMENT, `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY USING BTREE (`id`) ) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
INSERT INTO `tb_user` VALUES (1, 'smj', '123'); INSERT INTO `tb_user` VALUES (2, 'whb', '456');
|
项目分层
需要用到TomCat,请提前配置好
![20200703003555925](https://gist.github.com/assets/67999981/8873b120-8aa1-4ca5-b566-b89266512ac6)
util层
util层是用来配置数据库驱动,连接数据库以及关闭数据库引擎,直接封装在方法里的好处就是在Dao层中可以直接调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.sql.*;
public class DBUtil { public static Connection getConnection() throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/train","root","123456"); return connection; }
public static void closeAll(ResultSet resultSet, Statement statement,Connection connection) throws SQLException { if (resultSet!=null){ resultSet.close(); } if(statement!=null){ statement.close(); } if(connection!=null){ connection.close(); } } }
|
bean层
配置好数据库引擎后我们要开始把数据库中的字段放入一个类中,就相当于把数据库抽象为一个类,这个类中包含了所有需要的属性和get,set,tostring方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| public class User { public User() { }
public User(int id, String username, String password) { this.id = id; this.username = username; this.password = password; }
public User(String username, String password) { this.username = username; this.password = password; }
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 + '\'' + '}'; } }
|
Dao层
dao层用于数据库交互,也就是把数据库中的数据拿出来,这里我们需要从数据库中拿出username和password字段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| public class UserDao {
public User findUserByUserNameAndPassword(String username,String password){ Connection connection= null; PreparedStatement statement=null; ResultSet resultSet =null; User user=null; try { connection = DBUtil.getConnection(); String sql="select * from tb_user where username=? and password=?"; statement=connection.prepareStatement(sql); statement.setString(1,username); statement.setString(2,password); resultSet = statement.executeQuery(); while (resultSet.next()){ user=new User(); user.setId(resultSet.getInt(1)); user.setUsername(resultSet.getString(2)); user.setPassword(resultSet.getString(3));
} } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { try { DBUtil.closeAll(resultSet,statement,connection); } catch (SQLException throwables) { throwables.printStackTrace(); } } return user; } }
|
Service层
在业务层我们要写业务方法,这里要实现的是登录功能,首先要写一个userService接口,然后再写实现类实现这个接口
接口:
1 2 3
| public interface UserService { boolean login(String username,String password); }
|
实现类:
1 2 3 4 5 6 7 8 9 10 11 12
| public class UserServiceImpl implements UserService { UserDao userDao=new UserDao();
@Override public boolean login(String username, String password) { User user = userDao.findUserByUserNameAndPassword(username, password); if(user==null){ return false; }else { return true; } }
|
servlet层
servlet层的作用在ssm中类似于Controller,用来管理页面(及view层)
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class LoginServlet extends HttpServlet { UserService userService=new UserServiceImpl(); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username=req.getParameter("username"); String password=req.getParameter("password"); if(userService.login(username,password)){ resp.getWriter().write("success"); }else { resp.getWriter().write("failure"); } } }
|
view层
view层即网页,也就是jsp()
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <%-- 提交表单后跳转到login页面(在web.xml中定义),鼠标悬停在/login上自动提示要使用绝对路径,直接转化就行--%> <form action="${pageContext.request.contextPath}/login" method="post">使得 username:<input name="username" type="text"> password:<input name="password" type="password"> <input type="submit" value="login"> </form> </body> </html>
|
web.xml用来设置请求跳转到的页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <!-- LoginServlet的路径--> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.zr.servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <!-- 设置/login这个页面来向LoginServlet发送请求--> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> </web-app>
|
运行结果
用户名输入whb,密码输入456![20200703012436901](https://gist.github.com/assets/67999981/a52f3e2c-252b-4cc8-9f2e-9e79508997c1)
登录成功
![20200703012525241](https://gist.github.com/assets/67999981/c10e823c-d446-42c5-9efb-e51b8483033e)
用户名输入smj,密码输入456
登录失败
完成!