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

 更新时间:2024年10月11日 10:02:32   作者:VaporGas  
这篇文章介绍了如何使用三层架构(View, Service, DAO)和JDBCTemplate技术在JavaWeb环境下实现登录和注册功能,详细说明了构建项目的步骤,包括创建数据库表、实体类、DAO层、Service层、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进行登录和注册功能的实现项目 

总结 

到此这篇关于Java Web实战之使用三层架构与Servlet构建登录注册模块的文章就介绍到这了,更多相关Java Web构建登录注册模块内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中内部类的概念与分类详解

    Java中内部类的概念与分类详解

    一个类的定义放在另一个类的内部,这个类就叫做内部类,下面这篇文章主要给大家介绍了关于Java中内部类的概念与分类的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-09-09
  • Java统计50个10到50之间整数的随机出现次数

    Java统计50个10到50之间整数的随机出现次数

    这篇文章主要为大家详细介绍了Java统计50个10到50之间整数的随机出现次数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • Mybatis注解实现多数据源读写分离详解

    Mybatis注解实现多数据源读写分离详解

    这篇文章主要给大家介绍了关于Mybatis注解实现多数据源读写分离的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • 在 Spring Boot 项目中实现文件下载功能

    在 Spring Boot 项目中实现文件下载功能

    这篇文章主要介绍了在 Spring Boot 项目中实现文件下载功能,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • Java使用list集合remove需要注意的事项(使用示例)

    Java使用list集合remove需要注意的事项(使用示例)

    List集合的一个特点是它其中的元素是有序的,也就是说元素的下标是根据插入的顺序来的,在删除头部或者中间的一个元素后,后面的元素下标会往前移动,本文给大家介绍Java使用list集合remove需要注意的事项,感兴趣的朋友一起看看吧
    2022-01-01
  • Java注解方式之防止重复请求

    Java注解方式之防止重复请求

    这篇文章主要介绍了关于Java注解方式防止重复请求,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • JavaWeb学习过程之MVC查询模式详解

    JavaWeb学习过程之MVC查询模式详解

    这篇文章主要介绍了JavaWeb学习过程之MVC查询模式详解的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • 关于maven全局配置文件settings.xml解析

    关于maven全局配置文件settings.xml解析

    这篇文章主要介绍了关于maven全局配置文件settings.xml,具有很好的参考价值,希望对大家有所帮助。
    2022-03-03
  • 解决eclipse上传svn忽略target文件夹的坑

    解决eclipse上传svn忽略target文件夹的坑

    这篇文章主要介绍了解决eclipse上传svn忽略target文件夹的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • mybatis的Interceptor机制

    mybatis的Interceptor机制

    这篇文章主要为大家介绍了mybatis的Interceptor机制源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08

最新评论