IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> JavaWeb书城项目 -> 正文阅读

[系统运维]JavaWeb书城项目

1、表单验证的实现

在这里插入图片描述
现将文件拷贝进新的模块

然后完成以下需求

在这里插入图片描述
字母、数字、下划线组成,且长度是5-12,
由正则表达式表示为

var patt = /^\w{5,12}$/;
if(patt.test(usernameText)){
	alert("用户名合法!");
}else {
	alert("用户名不合法!");
}

邮箱部分也需要由正则表达式表示,可查看jQuery文档的 “其他” 里面

代码

<head>
<meta charset="UTF-8">
<title>尚硅谷会员注册页面</title>
<link type="text/css" rel="stylesheet" href="../../static/css/style.css" >
<style type="text/css">
	.login_form{
		height:420px;
		margin-top: 25px;
	}
</style>
	<script type="text/javascript" src="../../static/script/jquery-1.7.2.js"></script>
	<script type="text/javascript">
		$(function () {
			$("#sub_btn").click(function () {
				//验证用户名
				var patt = /^\w{5,12}$/;
				var usernameText = $("#username").val();
				if(!patt.test(usernameText)) {
					$("span.errorMsg").text("用户名不合法")
					return false
				}
				//验证密码
				var passwordText = $("#password").val();
				if(!patt.test(passwordText)) {
					$("span.errorMsg").text("密码不合法")
					return false
				}
				//验证确认密码
				var repwdText = $("#repwd").val();
				if(!(repwdText == passwordText)){
					$("span.errorMsg").text("密码不一致")
					return false
				}
				//邮箱验证
				var emailText = $("#email").val();
				var emailpatt = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
				if(!emailpatt.test(emailText)) {
					$("span.errorMsg").text("邮箱不合法")
					return false
				}
				//验证码
				var codeText = $("#code").val();
				//注意去掉前后空格
				var trim = $.trim(codeText);
				if(trim == null || trim == "") {
					$("span.errorMsg").text("验证码为空")
					return false
				}
				//注意当合法注册的时候注意需要清空提示的span里面的文本
				$("span.errorMsg").text("")
			})
		})
	</script>
</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="regist_success.html">
									<label>用户名称:</label>
									<input class="itxt" type="text" placeholder="请输入用户名" autocomplete="off" tabindex="1" name="username" id="username" />
									<br />
									<br />
									<label>用户密码:</label>
									<input class="itxt" type="password" placeholder="请输入密码" autocomplete="off" tabindex="1" name="password" id="password" />
									<br />
									<br />
									<label>确认密码:</label>
									<input class="itxt" type="password" placeholder="确认密码" autocomplete="off" tabindex="1" name="repwd" id="repwd" />
									<br />
									<br />
									<label>电子邮件:</label>
									<input class="itxt" type="text" placeholder="请输入邮箱地址" autocomplete="off" tabindex="1" name="email" id="email" />
									<br />
									<br />
									<label>验证码:</label>
									<input class="itxt" type="text" style="width: 150px;" id="code"/>
									<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>

2、用户注册和登陆

注意点:

  1. 在数据库连接操作的时候,导入properties配置文件的时候,不可以使用系统类加载器ClassLoader.getSystemResourceAsStream
  2. 在注册和登录的 html 页面中,表单提交的链接部分,链接填写的是提供的 Servlet 程序的链接,可以写相对路径和绝对路径
    1. 绝对路径:后续若使用请求中转会无法使用样式等文件(参考Servlet文章)
    2. 相对路径:需要写 base 标签,该页面内所有的相对路径都是相对于base标签中的路径,则页面的css样式以及 jquery的配置文件的路径全部要进行更改。
      跳转页面的时候可使用请求中转

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

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

JavaEE 项目的三层架构

在这里插入图片描述
分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级

在这里插入图片描述

2.1、数据库层

第三方 jar 包放在 web 目录的 WEB-INF 文件夹下
在这里插入图片描述

2.1.1、创建数据库

数据库存放用户注册的数据

2.1.2、定义 JavaBean 类

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

public class User {
    private int id;
    private String username;
    private String password;
    private String email;
}

2.1.3、编写工具类 JdbcUtils

使用 Druid 数据库连接池,导入 jar 包

在 src 源码目录下编写 jdbc.properties 属性配置文件
在这里插入图片描述
工具类 JdbcUtils 中封装数据库链接和关闭操作

注意,在连接操作中,如果使用ClassLoader.getSystemResourceAsStream(“文件名”),在后面项目运行的时候会报空指针异常

要使用jdbcUtils.class.getClassLoader().getResourceAsStream(“druid.properties”)

package com.atguigu.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.pool.DruidPooledConnection;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class jdbcUtils {
    private static DruidDataSource dataSource;
    static {
        try {
            Properties pro = new Properties();
            pro.load(jdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接(注意获取连接的操作不允许抛异常)
    //@return 如果返回null,说明获取连接失败
    public static Connection getconn(){

        DruidPooledConnection connection = null;
        try {
            connection = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  connection;
    }
    //关闭连接
    public static void close(Connection conn){
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

如果获取了数据库连接池的连接没有及时释放,就只能获取最大连接数的连接
在这里插入图片描述

但是如果及时的释放了连接,那获取几个连接都没有问题

在这里插入图片描述

2.2、DAO 层

2.2.1、编写 BaseDAO父类

package com.atguigu.DAO;

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.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public class BaseDAO<T> {
    private Class<T> clazz = null;
    {
        ParameterizedType parameterized = (ParameterizedType) this.getClass().getGenericSuperclass();
        Type[] type = parameterized.getActualTypeArguments();
        clazz = (Class<T>) type[0];
    }
    private QueryRunner qr = new QueryRunner();
    //通用的增删改操作
    public void update(Connection conn,String sql,Object...args){
        try {
            int i = qr.update(conn, sql, args);
            System.out.println("影响了" + i + "条数据");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    //通用的查询一条数据操作
    public T queryForOne(Connection conn,String sql,Object...args){
        T t = null;
        try {
            t = qr.query(conn,sql,new BeanHandler<T>(clazz),args);
            return t;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return t;
    }
    //通用的查询多条数据操作
    public List<T> queryForList(Connection conn,String sql,Object...args){
        List<T> list = null;
        try {
            list = qr.query(conn, sql, new BeanListHandler<T>(clazz), args);
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }
    //通用的查询特殊值的操作
    public Object queryForSingleValue(Connection conn,String sql,Object...args){
        Object o = null;
        try {
            o = qr.query(conn, sql, new ScalarHandler(), args);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return o;
    }
}

2.2.2、编写 UserDAO接口

package com.atguigu.DAO;

import com.atguigu.bean.User;
import java.sql.Connection;

public interface UserDAO {
    //根据用户名查询用户信息
    User queryUserByUsername(Connection connection, String username);
    //根据用户名和密码查询用户信息
    User queryUserByUsernameAndPassword(Connection connection,String username,String password);
    //保存用户信息(就是插一条用户信息数据)
    void saveUser(Connection connection,User user);
}

2.2.3、编写 UserDAOImpl

package com.atguigu.DAO.impl;

import com.atguigu.DAO.BaseDAO;
import com.atguigu.DAO.UserDAO;
import com.atguigu.bean.User;
import java.sql.Connection;

public class UserDAOImpl extends BaseDAO<User> implements UserDAO {
    @Override
    public User queryUserByUsername(Connection connection, String username) {
        String sql = "select * from `t_user` where username = ?";
        User user = queryForOne(connection, sql, username);
        return user;
    }
    @Override
    public User queryUserByUsernameAndPassword(Connection connection, String username, String password) {
        String sql = "select * from `t_user` where username = ? and password = ?";
        User user = queryForOne(connection, sql, username, password);
        return user;
    }
    @Override
    public void saveUser(Connection connection, User user) {
        String sql = "insert into `t_user`(`id`,`username`,`password`,`email`) values(?,?,?,?)";
        update(connection,sql,user.getId(),user.getUsername(),user.getPassword(),user.getEmail());
    }
}

2.3、Service 层

该层编写的是具体的业务

比如,登录、注册、验证用户名是否重复

2.3.1、编写 UserService接口

package com.atguigu.service;

import com.atguigu.bean.User;

public interface UserService {
    //这里是业务层
    //注册业务
    void registerUser(User user);
    //登录业务
    User login(User user);
    //检查用户名是否已经存在,若已存在,说明不可用
    boolean existsUsername(String username);
}

2.3.2、编写 UesrServiceImpl

package com.atguigu.service.impm;

import com.atguigu.DAO.UserDAO;
import com.atguigu.DAO.impl.UserDAOImpl;
import com.atguigu.bean.User;
import com.atguigu.service.UserService;
import com.atguigu.utils.jdbcUtils;
import java.sql.Connection;

public class UesrServiceImpl implements UserService {
    
    private UserDAO userDAO = new UserDAOImpl();
    
    @Override
    public void registerUser(User user) {
        Connection conn = jdbcUtils.getconn();
        userDAO.saveUser(conn,user);
        jdbcUtils.close(conn);
    }
    @Override
    public User login(User user) {
        Connection conn = jdbcUtils.getconn();
        User user1 = userDAO.queryUserByUsernameAndPassword(conn, user.getUsername(), user.getPassword());
        jdbcUtils.close(conn);
        return user1;
    }
    @Override
    public boolean existsUsername(String username) {
        Connection conn = jdbcUtils.getconn();
        User user = userDAO.queryUserByUsername(conn, username);
        jdbcUtils.close(conn);
        return user != null;
    }
}

2.4、Web 层

web.xml 文件中的配置

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

2.4.1、注册servlet

选择 POST 请求方式,是因为在转入网址之后,不会显现密码的内容

注册成功或者注册失败的时候,跳转页面使用的是 响应的请求重定向

package com.atguigu.web;

import com.atguigu.bean.User;
import com.atguigu.service.impm.UesrServiceImpl;
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 {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String email = request.getParameter("email");
        String code = request.getParameter("code");
        //验证验证码是否正确
        //本案例中将验证码写死,写成固定的字段abc,忽略大小写
        if("abc".equalsIgnoreCase(code)){
            //检查用户名是否可用
            UesrServiceImpl uesrService = new UesrServiceImpl();
            if(uesrService.existsUsername(username)){
                System.out.println("用户名已存在");
                response.sendRedirect("http://localhost:8080/book02/pages/user/regist.html");
            }else {
                //执行注册功能,保存数据
                User user = new User(username, password, email);
                uesrService.registerUser(user);
                //跳转到注册成功页面
                response.sendRedirect("http://localhost:8080/book02/pages/user/regist_success.html");
            }
        }else {
            System.out.println("验证码不正确");
            response.sendRedirect("http://localhost:8080/book02/pages/user/regist.html");
        }
    }
}

2.4.2、登录servlet

登录成功或者登录失败的时候,跳转页面使用的是 响应的请求重定向

package com.atguigu.web;

import com.atguigu.bean.User;
import com.atguigu.service.impm.UesrServiceImpl;
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 {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        UesrServiceImpl uesrService = new UesrServiceImpl();
        if(uesrService.login(new User(username,password,null)) != null){
            response.sendRedirect("http://localhost:8080/book02/pages/user/login_success.html");
        }else {
            System.out.println("登录失败");
            response.sendRedirect("http://localhost:8080/book02/pages/user/login.html");
        }
    }
}

2.5、html文件

登录页面的 html 文件中表单的提交链接

<form action="http://localhost:8080/book02/loginServlet" method="post">

注册页面的 html 文件中表单的提交链接

<form action="http://localhost:8080/book02/registServlet" method="post">

2.6、如果使用相对路径

  1. 添加 base 标签
<!--写 base 标签,永远固定相对路径跳转的结果-->
 <base href="http://localhost:8080/book/">
  1. 修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)
    以下是几个修改的示例:
 <link type="text/css" rel="stylesheet" href="static/css/style.css" > 
 <script type="text/javascript" src="static/script/jquery-1.7.2.js">
 </script>
  1. 修改 login.html 表单的提交地址和请求方式
    在这里插入图片描述
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章           查看所有文章
加:2021-12-22 12:55:39  更:2021-12-22 12:55:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 5:31:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码