书城第二阶段——用户注册和登陆

news2024/12/23 18:06:15

目录

  • 0.0 JavaEE 项目的三层架构
  • 0.1 项目阶段二:用户注册和登陆的实现。
  • 1、先创建书城需要的数据库和表。
  • 2、编写数据库表对应的JavaBean对象。
  • 3、编写工具类 JdbcUtils
    • 3.1、导入需要的 jar 包(数据库和连接池需要):
    • 3.2、在 src 源码目录下编写 jdbc.properties 属性配置文件:
    • 3.3、编写 JdbcUtils 工具类:
    • 3.4、JdbcUtils 测试
  • 4、编写 BaseDao
    • 4.1、导入 DBUtils 的 jar 包
    • 4.2、编写 BaseDao:
  • 5、编写 UserDao 和测试
  • 6、编写 UserService 和测试
  • 7、编写 web 层
    • 7.1、实现用户注册的功能
      • 7.1.1、图解用户注册的流程:
      • 7.1.2、修改 regist.html 和 regist_success.html 页面
      • 7.1.3、编写 RegistServlet 程序
  • 7.2、IDEA 中 Debug 调试的使用
    • 7.2.1、Debug 调试代码,首先需要两个元素:断点+ Debug 启动服务器
    • 7.2.2、测试工具栏:
    • 7.2.3、变量窗口
    • 7.2.4、方法调用栈窗口
  • 7.3、用户登录功能的实现
    • 7.3.1、图解用户登录
    • 7.3.2、修改 login.html 页面和 login_success.html 页面
    • 7.3.3、LoginServlet 程序

0.0 JavaEE 项目的三层架构

在这里插入图片描述

分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。

在这里插入图片描述

搭建书城项目开发环境:
在这里插入图片描述

0.1 项目阶段二:用户注册和登陆的实现。

需求 1:用户注册
需求如下:

1)访问注册页面
2)填写注册信息,提交给服务器
3)服务器应该保存用户
4)当用户已经存在----提示用户注册 失败,用户名已存在
5)当用户不存在-----注册成功

需求 2:用户登陆
需求如下:

1)访问登陆页面
2)填写用户名密码后提交
3)服务器判断用户是否存在
4)如果登陆失败 —>>>> 返回用户名或者密码错误信息
5)如果登录成功 —>>>> 返回登陆成功 信息

1、先创建书城需要的数据库和表。

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)
);
INSERT INTO t_user(`username`,`password`,`email`) VALUES('admin','admin','admin@atguigu.com');

SELECT * FROM t_user;

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

package com.atguigu.pojo;

public class User {
    private Integer id;
    private String username;
    private String password;
    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer 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;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                '}';
    }

    public User() {
    }

    public User(Integer id, String username, String password, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.email = email;
    }
}

3、编写工具类 JdbcUtils

3.1、导入需要的 jar 包(数据库和连接池需要):

druid-1.1.9.jar
mysql-connector-java-5.1.7-bin.jar
以下是测试需要:
hamcrest-core-1.3.jar
junit-4.12.jar

创建一个lib目录

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

添加jar包
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.2、在 src 源码目录下编写 jdbc.properties 属性配置文件:

添加配置文件,直接赋值到src目录下

在这里插入图片描述

在这里插入图片描述

jdbc.properties

username=root
password=abc123
url=jdbc:mysql://localhost:13306/book
driverClassName=com.mysql.jdbc.Driver
initialSize=5
maxActive=10

3.3、编写 JdbcUtils 工具类:

JdbcUtils

package com.atguigu.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import sun.applet.Main;

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

public class JdbcUtils {

    private static DruidDataSource dataSource;

    static {
        try {
            Properties properties = new Properties();
            // 读取 jdbc.properties属性配置文件
            InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            // 从流中加载数据
            properties.load(inputStream);
            // 创建 数据库连接 池
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }



    /**
     * 获取数据库连接池中的连接
     * @return 如果返回null,说明获取连接失败<br/>有值就是获取连接成功
     */
    public static Connection getConnection(){

        Connection conn = null;

        try {
            conn = dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return conn;
    }

    /**
     * 关闭连接,放回数据库连接池
     * @param conn
     */
    public static void close(Connection conn){
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

3.4、JdbcUtils 测试

JdbcUtilsTest中引入jar包

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

package com.atguigu.test;

import com.atguigu.utils.JdbcUtils;
import org.junit.Test;

import java.sql.Connection;

public class JdbcUtilsTest {

    @Test
    public void testJdbcUtils(){
        for (int i = 0; i < 100; i++){
            Connection connection = JdbcUtils.getConnection();
            System.out.println(connection);
            JdbcUtils.close(connection);//获取后要立即释放,没有这句就会只输出十条。
        }
    }

}

4、编写 BaseDao

4.1、导入 DBUtils 的 jar 包

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.2、编写 BaseDao:

BaseDao

package com.atguigu.dao.impl;

import com.atguigu.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;

public abstract class BaseDao {

    //使用DbUtils操作数据库
    private QueryRunner queryRunner = new QueryRunner();

    /**
     * update() 方法用来执行:Insert\Update\Delete语句
     *
     * @return 如果返回-1,说明执行失败<br/>返回其他表示影响的行数
     */
    public int update(String sql, Object... args) {
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.update(connection, sql, args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(connection);
        }
        return -1;
    }

    /**
     * 查询返回一个javaBean的sql语句
     *
     * @param type 返回的对象类型
     * @param sql  执行的sql语句
     * @param args sql对应的参数值
     * @param <T>  返回的类型的泛型
     * @return
     */
    public <T> T queryForOne(Class<T> type, String sql, Object... args) {
        Connection con = JdbcUtils.getConnection();
        try {
            return queryRunner.query(con, sql, new BeanHandler<T>(type), args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(con);
        }
        return null;
    }

    /**
     * 查询返回多个javaBean的sql语句
     *
     * @param type 返回的对象类型
     * @param sql  执行的sql语句
     * @param args sql对应的参数值
     * @param <T>  返回的类型的泛型
     * @return
     */
    public <T> List<T> queryForList(Class<T> type, String sql, Object... args) {
        Connection con = JdbcUtils.getConnection();
        try {
            return queryRunner.query(con, sql, new BeanListHandler<T>(type), args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(con);
        }
        return null;
    }

    /**
     * 执行返回一行一列的sql语句
     * @param sql   执行的sql语句
     * @param args  sql对应的参数值
     * @return
     */
    public Object queryForSingleValue(String sql, Object... args){

        Connection conn = JdbcUtils.getConnection();

        try {
            return queryRunner.query(conn, sql, new ScalarHandler(), args);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn);
        }
        return null;

    }

}

5、编写 UserDao 和测试

UserDao

package com.atguigu.dao;

import com.atguigu.pojo.User;

public interface UserDao {



    /**
     * 根据用户名查询用户信息
     * @param username 用户名
     * @return 如果返回null,说明没有这个用户。反之亦然
     */
    public User queryUserByUsername(String username);

    /**
     * 根据 用户名和密码查询用户信息
     * @param username
     * @param password
     * @return 如果返回null,说明用户名或密码错误,反之亦然
     */
    public User queryUserByUsernameAndPassword(String username,String password);

    /**
     * 保存用户信息
     * @param user
     * @return 返回-1表示操作失败,其他是sql语句影响的行数
     */
    public int saveUser(User user);

}

UserDaoImpl

package com.atguigu.dao.impl;

import com.atguigu.dao.UserDao;
import com.atguigu.pojo.User;

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(User.class, sql, username);
    }

    @Override
    public User queryUserByUsernameAndPassword(String username, String password) {
        String sql = "select `id`,`username`,`password`,`email` from t_user where username = ? and password = ?";
        return queryForOne(User.class, sql, 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());
    }
}

添加测试快捷键:

ctrl+shift+t
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

UserDaoTest

package com.atguigu.test;

import com.atguigu.dao.UserDao;
import com.atguigu.dao.impl.UserDaoImpl;
import com.atguigu.pojo.User;
import org.junit.Test;

import static org.junit.Assert.*;

public class UserDaoTest {

    UserDao userDao = new UserDaoImpl();

    @Test
    public void queryUserByUsername() {

        if (userDao.queryUserByUsername("admin1234") == null ){
            System.out.println("用户名可用!");
        } else {
            System.out.println("用户名已存在!");
        }
    }

    @Test
    public void queryUserByUsernameAndPassword() {
        if ( userDao.queryUserByUsernameAndPassword("admin","admin1234") == null) {
            System.out.println("用户名或密码错误,登录失败");
        } else {
            System.out.println("查询成功");
        }
    }

    @Test
    public void saveUser() {
        System.out.println( userDao.saveUser(new User(null,"wzg168", "123456", "wzg168@qq.com")) );
    }
}

6、编写 UserService 和测试

UserService

package com.atguigu.service;

import com.atguigu.pojo.User;

public interface UserService {
    /**
     * 注册用户
     * @param user
     */
    public void registUser(User user);

    /**
     * 登录
     * @param user
     * @return 如果返回null,说明登录失败,返回有值,是登录成功
     */
    public User login(User user);

    /**
     * 检查 用户名是否可用
     * @param username
     * @return 返回true表示用户名已存在,返回false表示用户名可用
     */
    public boolean existsUsername(String username);
}

UserServiceImpl

package com.atguigu.service.impl;

import com.atguigu.dao.UserDao;
import com.atguigu.dao.impl.UserDaoImpl;
import com.atguigu.pojo.User;
import com.atguigu.service.UserService;

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.queryUserByUsernameAndPassword(user.getUsername(), user.getPassword());
    }

    @Override
    public boolean existsUsername(String username) {

        if (userDao.queryUserByUsername(username) == null) {
           // 等于null,说明没查到,没查到表示可用
           return false;
        }

        return true;

    }
}

UserServiceTest

package com.atguigu.test;

import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import com.atguigu.service.impl.UserServiceImpl;
import org.junit.Test;

import static org.junit.Assert.*;

public class UserServiceTest {

    UserService userService = new UserServiceImpl();

    @Test
    public void registUser() {
        userService.registUser(new User(null, "bbj168", "666666", "bbj168@qq.com"));
        userService.registUser(new User(null, "abc168", "666666", "abc168@qq.com"));
    }

    @Test
    public void login() {
        System.out.println( userService.login(new User(null, "wzg168", "123456", null)) );
    }

    @Test
    public void existsUsername() {
        if (userService.existsUsername("wzg16888")) {
            System.out.println("用户名已存在!");
        } else {
            System.out.println("用户名可用!");
        }
    }
}

7、编写 web 层

7.1、实现用户注册的功能

7.1.1、图解用户注册的流程:

在这里插入图片描述

添加动态web服务器:

在这里插入图片描述

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


</web-app>

7.1.2、修改 regist.html 和 regist_success.html 页面

相对路径和绝对路径的选择:

web阶段使用:base+相对路径
框架之后使用:绝对路径

1、添加 base 标签

给注册页面添加base标签,后面的所有代码如果使用相对路径,都是相对于它来的

为regist添加:
在这里插入图片描述
2、修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)
哪个红改哪个
在这里插入图片描述

为regist_success.html添加在这里插入图片描述
3、修改注册表单的提交地址和请求方式
在这里插入图片描述

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

		<link type="text/css" rel="stylesheet" href="static/css/style.css" >
		<script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>
		<script type="text/javascript">
			// 页面加载完成之后
			$(function () {
				// 给注册绑定单击事件
				$("#sub_btn").click(function () {
					// 验证用户名:必须由字母,数字下划线组成,并且长度为5到12位
					//1 获取用户名输入框里的内容
					var usernameText = $("#username").val();
					//2 创建正则表达式对象
					var usernamePatt = /^\w{5,12}$/;
					//3 使用test方法验证
					if (!usernamePatt.test(usernameText)) {
						//4 提示用户结果
						$("span.errorMsg").text("用户名不合法!");

						return false;
					}

					// 验证密码:必须由字母,数字下划线组成,并且长度为5到12位
					//1 获取用户名输入框里的内容
					var passwordText = $("#password").val();
					//2 创建正则表达式对象
					var passwordPatt = /^\w{5,12}$/;
					//3 使用test方法验证
					if (!passwordPatt.test(passwordText)) {
						//4 提示用户结果
						$("span.errorMsg").text("密码不合法!");

						return false;
					}

					// 验证确认密码:和密码相同
					//1 获取确认密码内容
					var repwdText = $("#repwd").val();
					//2 和密码相比较
					if (repwdText != passwordText) {
						//3 提示用户
						$("span.errorMsg").text("确认密码和密码不一致!");

						return false;
					}

					// 邮箱验证:xxxxx@xxx.com
					//1 获取邮箱里的内容
					var emailText = $("#email").val();
					//2 创建正则表达式对象
					var emailPatt = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
					//3 使用test方法验证是否合法
					if (!emailPatt.test(emailText)) {
						//4 提示用户
						$("span.errorMsg").text("邮箱格式不合法!");

						return false;
					}

					// 验证码:现在只需要验证用户已输入。因为还没讲到服务器。验证码生成。
					var codeText = $("#code").val();

					//去掉验证码前后空格
					// alert("去空格前:["+codeText+"]")
					codeText = $.trim(codeText);
					// alert("去空格后:["+codeText+"]")

					if (codeText == null || codeText == "") {
						//4 提示用户
						$("span.errorMsg").text("验证码不能为空!");

						return false;
					}

					// 去掉错误信息
					$("span.errorMsg").text("");

				});

			});

		</script>
	<style type="text/css">
		.login_form{
			height:420px;
			margin-top: 25px;
		}

	</style>
	</head>
	<body>
		<div id="login_header">
			<img class="logo_img" alt="" src="static/img/logo.gif" >
		</div>

			<div class="login_banner">

				<div id="l_content">
					<span class="login_word">欢迎注册</span>
				</div>

				<div id="content">
					<div class="login_form">
						<div class="login_box">
							<div class="tit">
								<h1>注册尚硅谷会员</h1>
								<span class="errorMsg"></span>
							</div>
							<div class="form">
								<form action="registServlet" method="post">
									<label>用户名称:</label>
									<input class="itxt" type="text" placeholder="请输入用户名"
										   value="wzg168"
										   autocomplete="off" tabindex="1" name="username" id="username" />
									<br />
									<br />
									<label>用户密码:</label>
									<input class="itxt" type="password" placeholder="请输入密码"
										   value="123456"
										   autocomplete="off" tabindex="1" name="password" id="password" />
									<br />
									<br />
									<label>确认密码:</label>
									<input class="itxt" type="password" placeholder="确认密码"
										   value="123456"
										   autocomplete="off" tabindex="1" name="repwd" id="repwd" />
									<br />
									<br />
									<label>电子邮件:</label>
									<input class="itxt" type="text" placeholder="请输入邮箱地址"
										   value="wzg168@qq.com"
										   autocomplete="off" tabindex="1" name="email" id="email" />
									<br />
									<br />
									<label>验证码:</label>
									<input class="itxt" type="text" name="code" style="width: 150px;" id="code" value="abcde"/>
									<img alt="" src="static/img/code.bmp" style="float: right; margin-right: 40px">
									<br />
									<br />
									<input type="submit" value="注册" id="sub_btn" />
								</form>
							</div>

						</div>
					</div>
				</div>
			</div>
		<div id="bottom">
			<span>
				尚硅谷书城.Copyright &copy;2015
			</span>
		</div>
	</body>
</html>

7.1.3、编写 RegistServlet 程序

RegistServlet

package com.atguigu.web;

import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import com.atguigu.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;

public class RegistServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();


    //注册中有密码,密码不希望被别人看到,用doPost请求
    @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.existsUsername(username)) {
                System.out.println("用户名[" + username + "]已存在!");
//        跳回注册页面
                req.getRequestDispatcher("/pages/user/regist.html").forward(req, resp);
            } else {
                //      可用
//                调用Sservice保存到数据库
                userService.registUser(new User(null, username, password, email));
//
//        跳到注册成功页面 regist_success.html
                req.getRequestDispatcher("/pages/user/regist_success.html").forward(req, resp);
            }
        } else {
            System.out.println("验证码[" + code + "]错误");
            req.getRequestDispatcher("/pages/user/regist.html").forward(req, resp);
        }
    }
}

7.2、IDEA 中 Debug 调试的使用

7.2.1、Debug 调试代码,首先需要两个元素:断点+ Debug 启动服务器

1、断点,只需要在代码需要停的行的左边上单击,就可以添加和取消
2、Debug 启动 Tomcat 运行代码:

在这里插入图片描述

7.2.2、测试工具栏:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

7.2.3、变量窗口

变量窗口:它可以查看当前方法范围内所有有效的变量。
在这里插入图片描述

7.2.4、方法调用栈窗口

1、方法调用栈可以查看当前线程有哪些方法调用信息
2、下面的调用上一行的方法
在这里插入图片描述

其他常用调试相关按钮:

在这里插入图片描述

7.3、用户登录功能的实现

7.3.1、图解用户登录

在这里插入图片描述

7.3.2、修改 login.html 页面和 login_success.html 页面

login.html:
1、添加 base 标签
在这里插入图片描述
2、修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)
在这里插入图片描述

login_success.html:
1、添加 base 标签在这里插入图片描述
2、修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)
在这里插入图片描述

3、修改 login.html 表单的提交地址和请求方式
在这里插入图片描述

login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>尚硅谷会员登录页面</title>
	<!--写base标签,永远固定相对路径跳转的结果
	一般来说,一个工程中base地址是相同的。
	-->
	<base href="http://localhost:8081/Mbook/">

<link type="text/css" rel="stylesheet" href="static/css/style.css" >
</head>
<body>
		<div id="login_header">
			<img class="logo_img" alt="" src="static/img/logo.gif" >
		</div>
		
			<div class="login_banner">
			
				<div id="l_content">
					<span class="login_word">欢迎登录</span>
				</div>
				
				<div id="content">
					<div class="login_form">
						<div class="login_box">
							<div class="tit">
								<h1>尚硅谷会员</h1>
								<a href="regist.html">立即注册</a>
							</div>
							<div class="msg_cont">
								<b></b>
								<span class="errorMsg">请输入用户名和密码</span>
							</div>
							<div class="form">
								<form action="loginServlet" method="post">
									<label>用户名称:</label>
									<input class="itxt" type="text" placeholder="请输入用户名"
										   autocomplete="off" tabindex="1" name="username" />
									<br />
									<br />
									<label>用户密码:</label>
									<input class="itxt" type="password" placeholder="请输入密码"
										   autocomplete="off" tabindex="1" name="password" />
									<br />
									<br />
									<input type="submit" value="登录" id="sub_btn" />
								</form>
							</div>
							
						</div>
					</div>
				</div>
			</div>
		<div id="bottom">
			<span>
				尚硅谷书城.Copyright &copy;2015
			</span>
		</div>
</body>
</html>

login_success.html

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


<link type="text/css" rel="stylesheet" href="static/css/style.css" >
<style type="text/css">
	h1 {
		text-align: center;
		margin-top: 200px;
	}
	
	h1 a {
		color:red;
	}
</style>
</head>
<body>
		<div id="header">
				<img class="logo_img" alt="" src="static/img/logo.gif" >
				<div>
					<span>欢迎<span class="um_span">韩总</span>光临尚硅谷书城</span>
					<a href="../order/order.html">我的订单</a>
					<a href="../../index.html">注销</a>&nbsp;&nbsp;
					<a href="../../index.html">返回</a>
				</div>
		</div>
		
		<div id="main">
		
			<h1>欢迎回来 <a href="../../index.html">转到主页</a></h1>
	
		</div>
		
		<div id="bottom">
			<span>
				尚硅谷书城.Copyright &copy;2015
			</span>
		</div>
</body>
</html>

7.3.3、LoginServlet 程序

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_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>RegistServlet</servlet-name>
        <servlet-class>com.atguigu.web.RegistServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RegistServlet</servlet-name>
        <url-pattern>/registServlet</url-pattern>
    </servlet-mapping>



    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.atguigu.web.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/loginServlet</url-pattern>
    </servlet-mapping>





</web-app>

LoginServlet

package com.atguigu.web;

import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import com.atguigu.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;

public class LoginServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();

//    因为参数中有密码,所以用post请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//  1、获取请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 调用 userService.login()登录处理业务
        User loginUser = userService.login(new User(null, username, password, null));
        // 如果等于null,说明登录 失败!
        if (loginUser == null) {
            //   跳回登录页面
            req.getRequestDispatcher("/pages/user/login.html").forward(req, resp);
        } else {
            // 登录 成功
            //跳到成功页面login_success.html
            req.getRequestDispatcher("/pages/user/login_success.html").forward(req, resp);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197395.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

钉钉一键登录第三方网站

钉钉一键登录第三方网站序钉钉开发者后台H5微应用应用代码开发登录页面login.html登录实现LoginController.javapom.xml增加一键登录效果展示序 企业内部系统已经做过了钉钉扫码登录&#xff0c;现在需要添加钉钉一键登录第三方网站功能&#xff0c;这里主要记录一键登录整个实…

物联网终端设备的工作原理和功能讲解

物联网终端设备是实现数据采集和数据传输的设备&#xff0c;它连接了传感网络层和传输网络层&#xff0c;起到了数据采集、数据处理、数据加密和传输的功能。 物联网终端设备由传感器、外部传感接口、CPU和外部通讯组成&#xff0c;工作原理是通过外部传感接口与传感设备连接&a…

和平精英军需精打细算天花板,330拿下一整套军需

和平精英军需精打细算天花板&#xff0c;330拿下一整套军需&#xff01; #和平精英 #这游戏不花钱 #游戏凡星计划 军需精打细算天花板&#xff0c;一个月时间花 110 块获得 436 个军需币。拿个新军需的副套问题不大。要知道和平小店的暖弄大礼包&#xff0c; 100 左右&#…

一次在 classpath 使用通配符导致的偶发问题排查与建议

说起 Classpath&#xff0c;使用 Java 的同学应该都不会陌生。不过&#xff0c;目前的项目基本都会使用 Maven 等构建工具管理&#xff0c;开发过程中也会使用高度智能化的 IDE&#xff0c;在日常使用中直接涉及 Classpath 操作可能不多。前段时间遇到一个跟 Classpath 相关的偶…

【My Electronic Notes系列——触发器】

目录 序言&#xff1a; &#x1f3c6;&#x1f3c6;人生在世&#xff0c;成功并非易事&#xff0c;他需要破茧而出的决心&#xff0c;他需要永不放弃的信念&#xff0c;他需要水滴石穿的坚持&#xff0c;他需要自强不息的勇气&#xff0c;他需要无畏无惧的凛然。要想成功&…

【栈】单调栈详情介绍及其运用

单调栈单调栈的概述&#xff08;Overview&#xff09;何时使用单调栈模拟单调递增栈单调栈的运用&#xff08;算法练习题&#xff09;模板【练习一、单调栈】739. 每日温度【练习二、单调栈哈希表】496. 下一个更大元素 I【练习三、单调栈循环数组】503. 下一个更大元素 II【练…

Word处理控件Aspose.Words功能演示:使用 C++ 处理 Word 文档中的目录

Aspose API支持流行文件格式处理&#xff0c;并允许将各类文档导出或转换为固定布局文件格式和最常用的图像/多媒体格式。 Aspose.words是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和…

4EVERLAND IPFS CID部署,一键部署Uniswap

近日&#xff0c;4EVERLAND推出IPFS CID部署&#xff0c;开发者可以复制IPFS CID&#xff0c;一键部署到4EVERLAND。 一键部署&#xff0c;无需通过Github Repo&#xff0c;只需要知道CID即可。一键跨平台部署项目到 Arweave 或 ICP。了解IPFS CID&#xff0c;通过4EVERLAND绑…

漫谈广告机制设计 | 开篇语

很久没有写文章了&#xff0c;oCPC实践录的专栏还没有写完&#xff0c;我就换工作了&#xff0c;去了M公司&#xff0c;做的内容与oCPC不怎么相关&#xff0c;对于其中的问题思考也没有那么多了&#xff0c;好在专栏的核心思想已经基本阐明了。在M公司也已经快两年了&#xff0…

青龙+WxPusher实现资产推送

1.首先注册WXpusher&#xff1a; https://wxpusher.zjiecode.com/admin/login 扫码注册创建应用 确定完就会出现一个token&#xff0c;一定先复制保存起来&#xff0c;因为只显示一次&#xff0c;没存后期就只能重置了。 关闭后&#xff0c;这个页面有二维码和链接&#xff0…

CSS定位详解

文章目录定位为什么要使用定位定位的组成定位模式静态定位&#xff1a;按照标准流特性摆放&#xff0c;没有边偏移相对定位&#xff1a;元素在移动位置的时候&#xff0c;是相对于它原来的位置来说的绝对定位&#xff1a;在移动位置的时候相对与祖先元素固定定位&#xff1a;元…

C语言:指针详解

往期文章 C语言&#xff1a;初识C语言C语言&#xff1a;分支语句和循环语句C语言&#xff1a;函数C语言&#xff1a;数组C语言&#xff1a;操作符详解 目录往期文章前言1. 指针是什么2. 指针和指针类型3. 野指针4. 指针运算4.1 指针-整数4.2 指针-指针4.3 指针的关系运算5. 二…

“小灵通”的风雨往事

最近&#xff0c;有一部叫做《狂飙》的国产电视剧火遍全网&#xff0c;相信大家都看到了。在剧中&#xff0c;出现了一个通信名词&#xff0c;不知道在座各位有没有关注到。没错&#xff0c;这个名词&#xff0c;就是“小灵通”。《狂飙》剧的主角高启强&#xff0c;原本是个卖…

Web3.0 · 基础层技术 · SCQA模型趣谈密码学

【小木箱成长营】密码学系列教程&#xff1a; Web3.0 基础层技术 密码学在移动端应用与实践 一、序言 Hello&#xff0c;我是小木箱&#xff0c;欢迎来到小木箱成长营密码学系列教程&#xff0c;今天将分享 Web3.0 基础层技术 SCQA 模型趣谈密码学。 SCQA 模型趣谈密码学主…

第一章 opencv与python介绍及环境搭建

目录1.python安装2.opencv3.pycharm安装4.conda环境搭建(my)1.python安装 网上教程很多就不写了&#xff0c;推荐使用python3.8.2及以上版本 2.opencv opencv简单介绍&#xff1a;opencv是一个开源的计算机视觉库&#xff0c;可以在windows、MacOS、Linux等操作系统上运行。 …

Day878.count(*)问题 -MySQL实战

count(*)问题 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于count(*)问题。 在开发系统的时候&#xff0c;可能经常需要计算一个表的行数&#xff0c;比如一个交易系统的所有变更记录总数。 这时候可能会想&#xff0c;一条 select count(*) from t 语句不就解决…

【自动化测试】从0开始玩转docker—— 02软件配置

目的 CI / CD在目前各类互联网企业中已然成为推动软件开发行为的重要基础设施服务。同样的对于测试团队来说更是有着举足轻重的重大意义&#xff0c;无论是测试左移的具象化提现亦或是持续测试的顺利开展&#xff0c;掌握这一技能已是广大软件测试工程师的必修课。分享这一技术…

第一章:3D点云应用领域分析

&#x1f31e;欢迎来到点云的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; ✉️希望可以和大家一起完成进阶之路&#xff01; &#x1f64f;作者…

力扣(LeetCode)401. 二进制手表(2023.02.03)

二进制手表顶部有 4 个 LED 代表 小时&#xff08;0-11&#xff09;&#xff0c;底部的 6 个 LED 代表 分钟&#xff08;0-59&#xff09;。每个 LED 代表一个 0 或 1&#xff0c;最低位在右侧。 例如&#xff0c;下面的二进制手表读取 “3:25” 。 &#xff08;图源&#xff…

C语言基础知识(56)

下面的C程序的输出是什么#include<stdio.h>intmain(){int a 0;while(a <printf("HI")){a;}return0;}该代码将打印 3 次HI。 printf()函数将返回它正在打印的字符数&#xff0c;并将其与a进行比较。 由于 printf() 的返回值为 2&#xff0c;HI 将被打印 2 次…