• 【JavaWeb 实际项目 02】


    第一阶段:主要是通过jQuery对注册页面的用户名+密码+邮箱等作出的一些限制

    书城第二阶段 ===> 用户注册和登录

    第二阶段,我们要实现的是:

    • 注册输入的内容提交给服务器,然后服务器接收到以后,把数据保存到数据库内。
    • 登录输入用户名和密码之后,数据发送给服务器,服务器就会获取用户名和密码去数据库检查,如果正确跳转到登录成功页面,如果失败跳转到登录页面

    一、JavaEE三层架构介绍

    web层/视图展现层、Service业务层、Dao持久层 (编写持久层之前需要写Utils公共类来连接数据库,      

    BaseDao类来管理数据库的对象实现对数据库的增删改查,其他具体操作的对象的Dao,比如:UserDao等

     不同层级对应不同的包:

    web层        com.wufq.web/servlet/controller    

    service层    com.wufq.service          service接口包

              com.wufq.service.impl        service接口实现类

    dao持久层    com.wufq.dao            Dao接口包

            com.wufq.impl            Dao接口实现类

    实体bean对象     com.wufq.pojo/entity/domain/bean   javaBean类

    测试包     com.wufq.test/junit          

    工具类     com.wufq.utils

    --------项目开发环境---------

    二、代码编写流程

    1、创建数据库和表(这一阶段实现的是注册和登录,所以数据需要保存:id,用户名,密码,邮箱)

    DROP DATABASE IF EXISTS book;
    
    CREATE DATABASE book;
    
    USE book;
    
    CREATE TABLE t_user(
        id INT PRIMARY KEY AUTO_INCREMENT,
        username VARCHAR(20) NOT NULL UNIQUE,
        PASSWORD VARCHAR(32) NOT NULL,
        email VARCHAR(200)
        
    );
    
    DESC t_user;
    
    INSERT INTO t_user(username,PASSWORD,email) VALUES('admin','admin','admin@163.com');
    
    SELECT * FROM t_user;

    2、编写数据库表对应的JavaBean对象

    package com.wufq.pojo;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/6/25 11:07
     */
    public class User {
        private Integer id;
        private String username;
        private String password;
        private String email;
    
    //还包含getter、setter方法,toString方法、有参、无参构造器

    3、编写工具类JdbcUtils类 (管理数据库连接池:和数据库建立链接以及关闭链接)

    第一步:导入需要的jar包(数据库和连接池的jar包)

    |-- 在web包下创建lib目录,导入mysql,druid,junit包

    |-- 引入上面的jar包:file--Project Structure--Libraries--+(java)选择上面的lib目录,然后修改名称为book_lib --Modules--选择工程--切换到Dependencies

    --点击+号选择book_lib --Artifaces--选中工程名--点击fix

    第二步:在src源码目录下编写jdbc.properties属性配置文件

    username=root
    password=1234
    url=jdbc:mysql://172.16.203.130:3306/book?characterEncoding=utf-8&serverTimezone=GMT%2B8
    driverClassName=com.mysql.jdbc.Driver
    initialSize=5
    maxActive=10

    第三步:编写jdbcUtils工具类

    package com.wufq.utils;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Properties;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/6/25 11:13
     */
    public class JdbcUtils {
    
        private static DruidDataSource dataSource;
    
        static {
            try {
                Properties properties = new Properties();
                InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
                //2、从流中加载数据
                properties.load(inputStream);
                //1、创建数据库连接池
                dataSource =(DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        /*
        * 获取数据库连接池中的连接
        * 如果返回null,说明获取链接失败,有值就是获取链接成功
        * */
    
        public static Connection getConnection(){
            Connection conn=null;
            try {
                conn = dataSource.getConnection();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return conn;
        }
    
        /*
        * 关闭链接,放回数据库连接池
        * */
    
        public static void close(Connection conn){
    
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }

    第四步:JdbcUtils测试

    public class TestJdbcUtils {
    
        @Test
        public void testJdbcUtils(){
            for(int i=0;i<50;i++){
                Connection connection = JdbcUtils.getConnection();
                System.out.println(connection);
    //            这里一定要关闭数据库连接,因为配置文件内设置的最大连接数是:maxActive=10,如果不及时关闭连接,则只会创建10次连接
                JdbcUtils.close(connection);
            }
        }
    }

    编写Dao持久层

    4、编写BaseDao (给别人复用代码的作用)

    第一步:导入DButils的jar包

    commons-dbutils-1.3.jar

    第二步编写BaseDao

    package com.wufq.dao.impl;
    
    import com.wufq.utils.JdbcUtils;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.apache.commons.dbutils.handlers.ScalarHandler;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.List;
    
    /**
     * @Description  管理数据库对象,实现数据的增删改查
     * @Author wufq
     * @Version
     * @Date 2021/6/25 15:09
     */
    public abstract class BaseDao {
    
    //    使用DBUtils操作数据库
        private QueryRunner queryRunner = new QueryRunner();
    
        /*
        * updata()方法用来执行:insert/update/delete语句
        * @return 如果返回-1说明执行失败,返回其他表示影响的行数
        * */
    
        public int update(String sql,Object... args){ //Object... args可变参数的意思
            Connection conn = JdbcUtils.getConnection();
    
            try {
                return queryRunner.update(conn,sql,args);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.close(conn);
            }
    
            return -1;
        }
    
        /*
        * 查询返回一个javaBean的sql语句
        * type:返回对象类型
        * sql:执行的sql语句
        * args sql对应的参数
        * <T> 返回的类型的泛型
        * */
        public <T> T queryForOne(String sql,Class<T> type,Object... args){
            Connection conn = JdbcUtils.getConnection();
    
            try {
                return queryRunner.query(conn,sql,new BeanHandler<T>(type),args);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.close(conn);
            }
    
            return null;
        }
    
        /*
        * 查询返回多个javaBean的sql语句
        * type:返回对象类型
        * sql:执行的sql语句
        * args sql对应的参数
        * <T> 返回的类型的泛型
        * */
        public <T> List<T> queryForList(String sql, Class<T> type, Object... args){
            Connection conn = JdbcUtils.getConnection();
    
            try {
                return queryRunner.query(conn,sql,new BeanListHandler<T>(type),args);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.close(conn);
            }
    
            return null;
        }
    
        /*
        * 查询返回一行一列的sql语句
        * type:返回对象类型
        * sql:执行的sql语句
        * args sql对应的参数
        * <T> 返回的类型的泛型
        * */
        public Object queryForSingleValue(String sql,Object... args){
            Connection conn = JdbcUtils.getConnection();
    
            try {
                return queryRunner.query(conn,sql,new ScalarHandler(),args);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.close(conn);
            }
    
            return null;
        }
    }

    5、编写UserDao

    UserDao接口

    package com.wufq.dao;
    
    import com.wufq.pojo.User;
    
    /**
     * @Description User对象接口,验证用户信息在数据库内是否有效(比如:注册用户时首先根据用户名去数据库里面查找)
     * @Author wufq
     * @Version
     * @Date 2021/6/25 16:42
     */
    public interface UserDao {
    
     /*
      * 根据用户名查询用户信息
      * * @param username 用户名
      * @Return: com.wufq.pojo.User 如果返回null,说明没有这个用户,反之亦然
      *
      */
        public User queryUserByUsername(String username);
    
       /*
        * 根据用户名和密码查询用户信息
       * @param username
       * @param password
        * @Return: com.wufq.pojo.User
        *
        */
        public User queryUserByUsernameAndPasswd(String username,String password);
    
        /*
         * 保存用户信息
        * @param user
         * @Return: int 返回-1表示操作失败,其他是sql语句影响的行数
         *
         */
        public int saveUser(User user);
    
    }

    UserDaoImpl实现类

    package com.wufq.dao.impl;
    
    import com.wufq.dao.UserDao;
    import com.wufq.pojo.User;
    
    /**
     * @Description UserDao的具体实现类
     * @Author wufq
     * @Version
     * @Date 2021/6/25 17:28
     */
    public class UserDaoImpl extends BaseDao implements UserDao{
        @Override
        public User queryUserByUsername(String username) {
    
            String sql = "SELECT id,username,PASSWORD,email FROM `t_user` WHERE `username`=?";
            return queryForOne(sql,User.class,username);
        }
    
        @Override
        public User queryUserByUsernameAndPasswd(String username, String password) {
            String sql = "SELECT id,username,PASSWORD,email FROM `t_user` WHERE `username`=? and password=?";
    
            return queryForOne(sql,User.class,username,password);
        }
    
        @Override
        public int saveUser(User user) {
            String sql = "INSERT INTO t_user(username,PASSWORD,email) VALUES(?,?,?)";
    
            return update(sql,user.getUsername(),user.getPassword(),user.getEmail());
        }
    
    }

    测试UserDaoImpl

    package com.wufq.test;
    
    import com.wufq.dao.UserDao;
    import com.wufq.dao.impl.UserDaoImpl;
    import com.wufq.pojo.User;
    import org.junit.Test;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/6/25 17:41
     */
    public class UserDaoTest {
        UserDao userDao = new UserDaoImpl();
        @Test
        public void queryUserByUsername() throws Exception {
    
            if (userDao.queryUserByUsername("admin")==null) {
                System.out.println("用户名可用!");
            } else {
                System.out.println("用户名不存在!");
            }
    
        }
    
        @Test
        public void queryUserByUsernameAndPasswd() throws Exception {
            if(userDao.queryUserByUsernameAndPasswd("admin","admin")==null){
                System.out.println("用户名或密码错误,登录失败");
            }else{
                System.out.println("查询成功");
            }
        }
    
        @Test
        public void saveUser() throws Exception {
            System.out.println(userDao.saveUser(new User(null, "wufq123", "123456", "wufq@163.com")));
        }
    
    
    }

    6、编写UserService和测试

    UserService接口

    package com.wufq.service;
    
    import com.wufq.pojo.User;
    
    /**
     * @Description Dao持久层写完以后,按照javaEE三层架构我们写Service业务层
     * service层主要作用是:1、处理业务逻辑 2、调用持久层保存到数据库
     * @Author wufq
     * @Version
     * @Date 2021/6/28 10:23
     */
    
    /*
     *
    * @param 分析知道:登录是一个业务,注册也是一个业务,检查用户名是否存在也是一个业务
     * @Return:
     *
     */
    public interface UserService {
    
    /*
    * 注册用户
     * @param: user
    * @Return: void
    */
        public void registUser(User user);
    
        /*
        * 登录
         * @param: user
        * @Return: com.wufq.pojo.User
        */
        public User login(User user);
    
        /*
        * 检查用户名是否可用
         * @param: username
        * @Return: java.lang.Boolean
        */
        public Boolean existesUserName(String username);
    }

    UserServiceImpl实现类

    package com.wufq.service.impl;
    
    import com.wufq.dao.UserDao;
    import com.wufq.dao.impl.UserDaoImpl;
    import com.wufq.pojo.User;
    import com.wufq.service.UserService;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/6/28 13:01
     */
    public class UserServiceImpl implements UserService{
    
        private UserDao userDao = new UserDaoImpl();
    
        @Override
        public void registUser(User user) {
            userDao.saveUser(user);
        }
    
        @Override
        public User login(User user) {
            return userDao.queryUserByUsernameAndPasswd(user.getUsername(),user.getPassword());
        }
    
        @Override
        public Boolean existesUserName(String username) {
            if(userDao.queryUserByUsername(username)==null){
                return false;
            }
            return true;
        }
    }

    UserServiceTest测试类

    package com.wufq.test;
    
    import com.wufq.pojo.User;
    import com.wufq.service.UserService;
    import com.wufq.service.impl.UserServiceImpl;
    import org.junit.Test;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/6/28 13:28
     */
    public class UserServiceTest {
        UserService userService = new UserServiceImpl();
    
        @Test
        public void registUser() throws Exception {
            userService.registUser(new User(null,"bbj666","123456","bbj888@163.com"));
            userService.registUser(new User(null,"abc666","123456","abc888@163.com"));
        }
    
        @Test
        public void login() throws Exception {
            User login = userService.login(new User(null, "bbj888", "123456", null));
            System.out.println(login);
        }
    
        @Test
        public void existesUserName() throws Exception {
            System.out.println(userService.existesUserName("abc888"));
        }
    
    }

    编写web层

    7.1、实现用户注册的功能

    7.1.1 用户注册的流程

    7.1.2  新建RegistServlet类 -->此类继承HttpServlet(后面会详细写RegistServlet类的代码,当前新建是为了配置web服务器)-->编写web.xml文件

    <?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">
    <servlet>
        <servlet-name>RegistServlet</servlet-name>
        <servlet-class>com.wufq.web.RegistServlet</servlet-class>
    </servlet>  
        
    <servlet-mapping>
        <servlet-name>RegistServlet</servlet-name>
        <url-pattern>/registServlet</url-pattern>
    </servlet-mapping>    
    </web-app>

    -->修改tomcat配置文件(Edit Configuration)

    7.1.3  修改regist.html 和regist_success.html页面

    前端跳转地址一般分为两种:

    1)base标签+相对路径

    2)绝对路径

    这里我们使用base标签+相对路径,后面使用框架的时候用绝对路径

    • 添加base标签
    <head>
    <meta charset="UTF-8">
    <title>尚硅谷会员注册页面</title>
    <!--写base标签,永远固定相对路径跳转的结果-->
    <base href="http://localhost:8080/book/">

    当用了base标签以后,启动服务器前端页面跳转到注册页时会发现整个css和jQery文件引用都失效了,失效的原因:base标签对页面中所有相对路径的影响

    • 修改base标签对页面中所有相对路径的影响(浏览器F12-->network 那个报红,修改那个)

    以下是修改的示例:
    修改前
    <script type="text/javascript" src="../../static/script/jquery-1.7.2.js"></script>
    修改后
    <script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>
    • 修改注册表单的提交地址和请求方式

    7.1.4  编写RegistServlet程序

    package com.wufq.web;
    
    import com.wufq.pojo.User;
    import com.wufq.service.UserService;
    import com.wufq.service.impl.UserServiceImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/6/28 16:00
     */
    public class RegistServlet extends HttpServlet{
    
        private UserService userService = new UserServiceImpl();
    
        /*
        *  按照用户注册流程中RegistServlet程序接受客户端后处理请求的流程
         * @param: req
         * @param: resp
        * @Return: void
        */
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        1、获取请求的参数
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            String email = req.getParameter("email");
            String code = req.getParameter("code");
    
    //        2、检查验证码是否正确  ===  写死,要求验证码为:abcde  (一般验证码由服务器生成,这个先写死)
            if("abcde".equalsIgnoreCase(code)){
    //            3、验证码正确,在继续检查用户名是否可用
                if(userService.existesUserName(username)){
                    //用户名存在,跳回注册页面
                    System.out.println("用户名["+username+"]已存在");
                    req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
                }else {
                    //用户名不存在,调用UserService保存在数据库,并且页面跳转到注册成功页面
                    userService.registUser(new User(null,username,password,email));
                    req.getRequestDispatcher("/pages/user/regist_success.html").forward(req,resp);
                }
            }else{
    //            4、不正确,页面跳转仍然跳转到注册页面
                System.out.println("验证码["+code+"]错误");
                req.getRequestDispatcher("pages/user/regist.html").forward(req,resp);
            }
    
        }
    }

     7.2 实现用户登录的功能

    7.2.1 用户登录流程

    7.2.2 在login.html和login_success.html页面添加base标签和表单的请求方式(action="loginServlet" method="post")

    7.2.3 LoginServlet程序

    package com.wufq.web;
    
    import com.wufq.pojo.User;
    import com.wufq.service.UserService;
    import com.wufq.service.impl.UserServiceImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/6/29 09:04
     */
    public class LoginServlet extends HttpServlet{
    
        private UserService userService = new UserServiceImpl();
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        1、获取请求的参数
            String username = req.getParameter("username");
            String password = req.getParameter("password");
    
    //        2、调用userService.login()登录处理业务
            User loginUser = userService.login(new User(null, username, password, null));
    
            if(loginUser ==null){
                System.out.println("登录失败!");
                req.getRequestDispatcher("/pages/user/login.html").forward(req, resp);
            }else {
                System.out.println("欢迎["+username+"]登录尘封网");
                req.getRequestDispatcher("/pages/user/login_success.html").forward(req, resp);
            }
    
        }
    }
  • 相关阅读:
    一文搞定 Spring Boot & Shiro 实战
    CPU 到底是怎么认识代码的?涨姿势了!
    Java 可重入锁内存可见性分析
    大牛总结的 Git 使用技巧,写得太好了!
    厉害了,如何搭建一套自己的私有网盘?
    深入浅出 Java 中 JVM 内存管理
    SLA服务可用性4个9是什么意思?怎么达到?
    解决springboot配置@ControllerAdvice不能捕获NoHandlerFoundException问题
    mybatis多参数使用方法且其中有的参数是多个值使用in查询
    Optional导致的 java.util.NoSuchElementException: No value present
  • 原文地址:https://www.cnblogs.com/frankruby/p/14927999.html
Copyright © 2020-2023  润新知