当前位置: 首页 > article >正文

Java Web实战:利用三层架构与Servlet构建登录注册模块

 前言导读

三层架构:View(视图层)Service(业务层)DAO(持久层)

  • 使用了JDBCtemplate技术,封装了原生的JDBC技术操作MySQL数据库(DAO层)
  • 实现了登录功能和注册功能(Service层)
  • 使用Servlet操作前端表单提供的数据,进行登录和注册,以及完成页面跳转的需求实现(View层)

 第一步:创建JavaWeb项目,在pom.xml中配置相关依赖

 pom.xml

        不要把我的项目名也一起复制了,只复制依赖<dependency>和插件部分<build>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>maven_9_11</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>maven_9_11 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <!-- junit单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <!--MySQL数据库连接驱动jar包-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.28</version>
    </dependency>
    <!-- servlet依赖支持-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <!--JDBCTemplate依赖支持,因为JDBCTemplate是Spring框架封装的一个工具类,因此需要导入Spring相关依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.4</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>5.3.4</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.8.RELEASE</version>
    </dependency>

  </dependencies>
  <build>
    <!--配置项目名 -->
    <finalName>web</finalName>
    <plugins>
    <!--配置jetty服务器插件支持-->
    <plugin>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-maven-plugin</artifactId>
      <version>9.3.14.v20161028</version>
    </plugin>
      <!--配置tomcat服务器插件支持-->
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.1</version>
      <configuration>
        <port>8080</port>
        <path>/</path>
        <uriEncoding>UTF-8</uriEncoding>
        <server>tomcat7</server>
      </configuration>
    </plugin>
    </plugins>
  </build>
</project>

第二步:创建数据库表和实体类并导入JDBCTemplate工具类

数据库表t_user:

这里不介绍如何创建这样的一个数据库了(保证user_id为主键即可)

User实体类:

package com.csx.entity;

import java.io.Serializable;

public class User implements Serializable {
    private Integer userId;
    private String userName;
    private String password;

    public User(){}

    public User(Integer userId, String userName, String password) {
        this.userId = userId;
        this.userName = userName;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    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;
    }
}

工具类:

package com.csx.util;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtils {
    private static DataSource dataSource =null;

    static{
        try (
                InputStream is=JDBCUtils.class.getResourceAsStream("/JDBCUtils.properties")
        ){
            Properties p = new Properties();
            p.load(is);
            dataSource = new DriverManagerDataSource(p.getProperty("url"), p.getProperty("username"), p.getProperty("password"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static JdbcTemplate getJDBCTemplate(){
        //创建JDBCTemplate对象并传入数据库连接池
        JdbcTemplate template = new JdbcTemplate(dataSource);
        return template;
    }

    /**
     * 获取数据库连接池
     * @return
     */
    public static DataSource getDataSource(){
        return dataSource;
    }

    /**
     * 开始线程绑定 +获取连接
     * @return
     */
    public static Connection startTransaction(){
        if (!TransactionSynchronizationManager.isSynchronizationActive()){
            TransactionSynchronizationManager.initSynchronization();
        }
        Connection connection =DataSourceUtils.getConnection(dataSource);
        try {
            connection.setAutoCommit(false);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return connection;
    }

    /**
     * 提交事务
     * @param conn
     */
    public static void commit(Connection conn){
        try {
            conn.commit();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            clear(conn);
        }
    }

    /**
     * 回滚事务
     * @param conn
     */
    public static void rollback(Connection conn){
        try {
            conn.rollback();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            clear(conn);
        }
    }


    /**
     * 解除线程绑定+释放资源+归还连接到线程池
     * @param conn
     */
    public static void clear(Connection conn){
        //清除线程绑定的资源
        TransactionSynchronizationManager.clear();
        TransactionSynchronizationManager.unbindResourceIfPossible(dataSource);
        //归还数据库连接至连接池
        if (conn!=null){//非空判断,判断为空再归还
            DataSourceUtils.releaseConnection(conn,dataSource);
        }
    }

}

在resources资源目录下创建JDBCUtils.properties目录

JDBCUtils.properties

url=jdbc:mysql://localhost:3306/csx_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimeZone=Asia/shanghai
username=root
password=root

第三步:创建DAO层,书写SQL支持

UserDao接口:

package com.csx.dao;

import com.csx.entity.User;

public interface UserDao {
    /**
     * 根据用户名和密码指定用户是否存在
     * @param userName
     * @return
     */
    public User selectUserByUserName(String userName,String password);

    /**
     * 新增用户信息
     * @param user
     * @return
     */
    public int insertUser(User user);

}

UserDaoImpl实现类:

package com.csx.dao.impl;

import com.csx.dao.UserDao;
import com.csx.entity.User;
import com.csx.service.UserService;
import com.csx.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

public class UserDaoImpl implements UserDao {
    private JdbcTemplate template = JDBCUtils.getJDBCTemplate();


    /**
     * 根据用户名和密码指定用户是否存在
     *
     * @param userName
     * @param password
     * @return
     */
    @Override
    public User selectUserByUserName(String userName, String password) {
        String sql="select * from t_user where user_name=? and password=? ";
        List<User> list = template.query(sql, new BeanPropertyRowMapper<>(User.class), userName, password);
        return list.isEmpty()?null:list.get(0);
    }

    /**
     * 新增用户信息
     *
     * @param user
     * @return
     */
    @Override
    public int insertUser(User user) {
        String sql="insert into t_user(user_name,password) values(?,?)";
        return template.update(sql, user.getUserName(), user.getPassword());
    }
}

第四步:创建Service层,书写登录和注册逻辑

UserService接口:

package com.csx.service;

public interface UserService {


    /**
     * 用户登录功能
     * @param username
     * @param password
     * @return
     */
    public boolean login(String username,String password);

    /**
     * 用户注册功能
     * @return
     */
    public boolean register(String username,String password);
}

UserServiceImpl实现类:

package com.csx.service.impl;

import com.csx.dao.UserDao;
import com.csx.dao.impl.UserDaoImpl;
import com.csx.entity.User;
import com.csx.service.UserService;
import com.csx.util.JDBCUtils;

import java.sql.Connection;

public class UserServiceImpl implements UserService {
    private UserDao userDao =new UserDaoImpl();

    /**
     * 用户登录功能
     *
     * @param username
     * @param password
     * @return
     */
    @Override
    public boolean login(String username, String password) {
        boolean boo =false;
        Connection conn =null;
        try{
            conn= JDBCUtils.startTransaction();
            //业务功能
            User user = userDao.selectUserByUserName(username,password);
            //判断用户名是否存在
            if (user!=null){
                //判断密码是否正确
                if (user.getPassword().equals(password)){
                    boo=true;
                }else {
                    throw new RuntimeException("密码错误!");
                }
            }else {
                throw new RuntimeException("用户不存在!");
            }
            JDBCUtils.commit(conn);
        }catch (Exception e){
            JDBCUtils.rollback(conn);
            throw new RuntimeException(e);
        }
        return boo;

    }

    /**
     * 用户注册功能
     *
     * @param username
     * @param password
     * @return
     */
    @Override
    public boolean register(String username, String password) {
        boolean boo=false;
        Connection conn=null;
        try {
            conn = JDBCUtils.startTransaction();
            //业务功能
            User u = userDao.selectUserByUserName(username,password);
            if (u == null) {
                User user = new User(null, username, password);
                userDao.insertUser(user);
                boo = true;
            } else {
                throw new RuntimeException("用户名重复,注册失败!");
            }
            JDBCUtils.commit(conn);
        }catch (Exception e){
            JDBCUtils.rollback(conn);
            throw  new RuntimeException(e);
        }
        return boo;
    }
}

第五步:书写Servlet接收页面传入的数据,并响应

LoginServlet:

package com.csx.servlet;

import com.csx.service.UserService;
import com.csx.service.impl.UserServiceImpl;

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;
import java.io.PrintWriter;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    private UserService userService =new UserServiceImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String name = request.getParameter("username");
        String pwd =request.getParameter("password");
        try {
            boolean login = userService.login(name, pwd);
            if (login){
                System.out.println("登录成功!");
                response.sendRedirect("login_success.html");
            }else {

                }
        } catch (Exception e) {
            System.out.println("登录失败");
            response.sendRedirect("login_failed.html");
        }


    }
}

RegisterServlet:

package com.csx.servlet;

import com.csx.service.UserService;
import com.csx.service.impl.UserServiceImpl;

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("/register")
public class RegisterServlet extends HttpServlet {
    private UserService userService =new UserServiceImpl();
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("username");
        String pwd =request.getParameter("password");
        try {
            boolean login = userService.register(name, pwd);
            if (login){
                System.out.println("注册成功!");
//                response.sendRedirect("register_success.html");
                response.sendRedirect("register_success.html");
            }
        } catch (Exception e) {
            System.out.println("注册失败!");
            response.sendRedirect("register_failed.html");
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
}

web.xml配置 

创建一个JavaWeb项目,想要使用注解@WebServlet来配置Servlet路径映射,需要将webapp目录下的WBE-INF目录下的web.xml中配置3.0 以上的配置头,例如:

<?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_3_1.xsd"
         version="3.1">

</web-app>

 第六步:在webapp目录下创建HTML页面

login.html:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Form</title>
    <style>
        /* 简单的样式来美化表单 */
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }
        .login-form {
            padding: 20px;
            background: white;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        .login-form h2 {
            margin-bottom: 20px;
        }
        .login-form input[type="text"],
        .login-form input[type="password"] {
            width: calc(100% - 22px);
            padding: 10px;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        .login-form input[type="submit"] {
            background-color: #ff0000;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .login-form input[type="submit"]:hover {
            background-color: #0056b3;
        }
    </style>
</head>
<body>

<div class="login-form">
    <h2>Login</h2>
    <form action="/login" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required>

        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required>

        <input type="submit" value="Login">
    </form>
</div>
</body>
</html>

login_success.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录成功!</h1>
</body>
<script>alert('登录成功!')</script>
</html>

login_failed:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录失败</h1>
</body>
<script>
    alert('登录失败')
</script>
</html>

register.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Registration Form</title>
    <style>
        /* 简单的样式来美化表单 */
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }
        .registration-form {
            padding: 20px;
            background: white;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        .registration-form h2 {
            margin-bottom: 20px;
        }
        .registration-form input[type="text"],
        .registration-form input[type="password"] {
            width: calc(100% - 22px);
            padding: 10px;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        .registration-form input[type="submit"] {
            background-color: #28a745;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .registration-form input[type="submit"]:hover {
            background-color: #218838;
        }
    </style>
</head>
<body>

<div class="registration-form">
    <h2>Registration</h2>
    <form action="/register" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required>

        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required>

        <input type="submit" value="Register">
    </form>
</div>

</body>
</html>

register_success:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Form</title>
    <style>
        /* 简单的样式来美化表单 */
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }
        .login-form {
            padding: 20px;
            background: white;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        .login-form h2 {
            margin-bottom: 20px;
        }
        .login-form input[type="text"],
        .login-form input[type="password"] {
            width: calc(100% - 22px);
            padding: 10px;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        .login-form input[type="submit"] {
            background-color: #ff0000;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .login-form input[type="submit"]:hover {
            background-color: #0056b3;
        }
    </style>
</head>
<body>

<div class="login-form">
    <h2>Login</h2>
    <form action="/login" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required>

        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required>

        <input type="submit" value="Login">
    </form>
</div>
</body>
<script>
    alert(' 注册成功,请登录!');

   </script>
</html>

register_failed:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Registration Form</title>
    <style>
        /* 简单的样式来美化表单 */
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }
        .registration-form {
            padding: 20px;
            background: white;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        .registration-form h2 {
            margin-bottom: 20px;
        }
        .registration-form input[type="text"],
        .registration-form input[type="password"] {
            width: calc(100% - 22px);
            padding: 10px;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        .registration-form input[type="submit"] {
            background-color: #28a745;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .registration-form input[type="submit"]:hover {
            background-color: #218838;
        }
    </style>
</head>
<body>

<div class="registration-form">
    <h2>Registration</h2>
    <form action="/register" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required>

        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required>

        <input type="submit" value="Register">
    </form>
</div>

</body>
<script>
    alert("注册失败!")
</script>
</html>

第七步:项目启动与测试 

项目启动,参考我的这篇博客:JavaWeb项目启动

运行测试

登录

登录失败

登录成功

注册

注册成功

注册成功会直接跳转到登录页面

注册失败

注册失败,弹出警告框,并且返回注册页面

总结

整体结构图

忽略我没有在博客书写的类和html页面,它们是我自己测试时使用的,不影响整体功能执行

基于三层架构和Servlet进行登录和注册功能的实现项目 


http://www.kler.cn/a/312138.html

相关文章:

  • [CKS] Audit Log Policy
  • element-plus的Tree 树形控件添加图标
  • 【DM系列】DM 集成 JDBC 开发指南
  • 「C/C++」C++ STL容器库 之 std::map 键值容器类
  • 【SQL实验】更新操作
  • 【Linux】【Vim】多文件编辑与分屏
  • 828华为云征文 | 云服务器Flexus X实例:部署 AgentOps,全方位监测智能体
  • Find My资讯|AirPods 4标准版充电盒无扬声器,Find My查找不会发出声音
  • Vue3:编写一个插件(进阶)
  • neuroph建立简单BP网络
  • windows消息机制
  • Spring Boot 项目中整合 RabbitMQ,使用死信队列(Dead Letter Exchange, DLX)实现延迟队列功能
  • 设计模式 组合模式(Composite Pattern)
  • 【HTTP】认识 URL 和 URL encode
  • KL散度(Kullback-Leibler)
  • java框架
  • 深入理解 MySQL MVCC:多版本并发控制的核心机制
  • vmware,centos8(虚拟机) 的安装
  • Python Web开发中的持续集成与持续交付(CI/CD)
  • cassandra指定配置文件的docker启动方法
  • 【学术会议征稿】第四届计算机、信息工程与电子材料国际学术会议 (CTIEEM 2024)
  • 微信小程序能不能有一种公共的分包,能被普通的分包引用其资源?(内有解决方案)
  • 【测试】博客系统测试报告
  • docker面经
  • 【Mac】系统环境配置
  • mybatisplus分页查询学习