《尚硅谷》JavaWeb课程书城项目笔记——第二阶段:用户注册与登陆页面相关业务的实现

目录

1、组建架构

2、创建数据库表格用于接收数据

3、创建JavaBean对象

4、编写JdbcUtils工具类

5、编写BaseDao类,用于实现对数据库的修改和查询

6、编写接口UserDao与类UserDaoImpl,实现注册功能与登陆功能

7、实现注册、登陆、用户名查询业务

8、使用客户端注册账户功能的实现

9、使用客户端登陆账户功能的实现


1、组建架构

2、创建数据库表格用于接收数据

数据库版本:MySQL5.7

3、创建JavaBean对象

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

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

    public User() {
    
    }

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

4、编写JdbcUtils工具类

导入Jar包

编写配置文件用于连接数据库

编写数据库初始化程序与获取、关闭连接代码

package utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import java.io.IOException;
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,说明获取连接失败;否则则是获取连接成功
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

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

测试JdbcUtils功能

  • 导入相关Jar包

  • 编写测试程序
public class JdbcUtilsTest {

    @Test
    public void test() {
        for (int i = 0; i < 15; i++) {
            Connection conn = JdbcUtils.getConnection();
            System.out.println(conn);
            JdbcUtils.closeConnection(conn);
        }
    }
}

5、编写BaseDao类,用于实现对数据库的修改和查询

导入Jar包

编写代码

package dao.impl;

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 utils.JdbcUtils;

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,代表操作失败;否则返回值代表此次操作影响的行数
     */
    public int update(String sql,Object...args){
        Connection conn = JdbcUtils.getConnection();
        try {
            return queryRunner.update(conn,sql,args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(conn);
        }
        return -1;
    }

    /**
     * queryForOne()查询返回一行数据
     * @param type  返回对象类型
     * @param sql   查询的sql语句
     * @param args  查询的参数
     * @param <T>   返回类型的泛型
     * @return  如果返回值为null,代表操作失败;否则返回查询到的对象
     */
    public <T> T queryForOne(Class<T> type,String sql,Object...args) {
        Connection conn = JdbcUtils.getConnection();
        try {
            return queryRunner.query(conn,sql,new BeanHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(conn);
        }
        return null;
    }

    /**
     * queryForList()   查询返回多行数据
     * @param type  返回对象类型
     * @param sql   查询的sql语句
     * @param args  查询的参数
     * @param <T>   返回类型的泛型
     * @return  如果返回值为null,代表操作失败;否则返回查询到的对象
     */
    public <T>List<T> queryForList(Class<T> type,String sql,Object...args) {
        Connection conn = JdbcUtils.getConnection();
        try {
            return queryRunner.query(conn,sql,new BeanListHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(conn);
        }
        return null;
    }

    /**
     * queryForSingleValue()    查询返回一行一列数据
     * @param sql   查询的sql语句
     * @param args  sql语句的参数
     * @return  如果返回值为null,代表操作失败;否则返回查询到的单个数据
     */
    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.closeConnection(conn);
        }
        return null;
    }
}

6、编写接口UserDao与类UserDaoImpl,实现注册功能与登陆功能

UserDao接口

package dao;

import pojo.User;

public interface UserDao {
    /**
     * 根据用户名查询用户信息
     * @param username 用户名
     * @return  如果返回值为null,代表当前用户名不存在
     */
    public User queryByUsername(String username) ;

    /**
     * 保存用户信息
     * @param user
     * @return 如果返回值为-1,代表操作失败;否则返回此次操作影响的行数
     */
    public int saveUser(User user);

    /**
     * 根据用户名和密码查询用户信息
     * @param username  用户名
     * @param password  密码
     * @return  如果返回值为null,代表用户名或密码错误;否则返回用户信息
     */
    public User queryByUsernameAndPassword(String username,String password);
}

UserDaoImpl类

package dao.impl;

import dao.UserDao;
import pojo.User;

public class UserDaoImpl extends BaseDao implements UserDao {
    @Override
    public User queryByUsername(String username) {
        String sql = "select `id`,`username`,`password`,`email` from t_user where username=?";
        return queryForOne(User.class,sql,username);
    }

    @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());
    }

    @Override
    public User queryByUsernameAndPassword(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);
    }
}

测试UseDao功能

package test;

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

import static org.junit.Assert.*;

public class UserDaoTest {

    UserDao userDao = new UserDaoImpl();

    @Test
    public void queryByUsername() {
        if(userDao.queryByUsername("admin") == null) {
            System.out.println("当前用户名可用");
        } else {
            System.out.println("此用户名已存在!");
        }
    }

    @Test
    public void saveUser() {
        if(userDao.saveUser(new User(null,"asd123","123456",null)) == -1) {
            System.out.println("注册失败!");
        } else {
            System.out.println("注册成功");
        }
    }

    @Test
    public void queryByUsernameAndPassword() {
        if(userDao.queryByUsernameAndPassword("admin","admin") == null) {
            System.out.println("登录失败!");
        } else {
            System.out.println("登陆成功");
        }
    }
}

7、实现注册、登陆、用户名查询业务

编写UserService

package service;

import pojo.User;

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

    /**
     * 检查用户名是否存在
     * @param username 用户名
     * @return 如果返回值为false,表示用户名不存在;否则表示已存在
     */
    public boolean existsUsername(String username);

    /**
     * 实现用户登陆
     * @param username  用户名
     * @param password  密码
     * @return 如果返回值为null,表示用户名或密码错误;否则返回用户信息
     */
    public User login(String username,String password);
}

编写UserServiceImpl

package service.impl;

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

public class UserServiceImpl implements UserService {

    UserDao userDao = new UserDaoImpl();

    @Override
    public void registUser(User user) {
        userDao.saveUser(user);
    }

    @Override
    public boolean existsUsername(String username) {
        if(userDao.queryByUsername(username) == null) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public User login(String username, String password) {
        if(userDao.queryByUsernameAndPassword(username,password) != null) {
            return userDao.queryByUsernameAndPassword(username,password);
        }
        return null;
    }
}

测试UserService及UserServiceImpl

package test;

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

import static org.junit.Assert.*;

public class UserServiceTest {

    UserService userService = new UserServiceImpl();

    @Test
    public void registUser() {
        userService.registUser(new User(null,"zxc123","123456","zxc123@163.com"));
    }

    @Test
    public void existsUsername() {
        if(userService.existsUsername("zxc123")) {
            System.out.println("已存在");
        } else {
            System.out.println("可以用");
        }
    }

    @Test
    public void login() {
        if(userService.login("zxc123","123456") == null) {
            System.out.println("用户名或密码错误");
        } else {
            System.out.println("登陆成功");
        }
    }
}

8、使用客户端注册账户功能的实现

编写RegistServlet

package web;

import pojo.User;
import service.UserService;
import 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();

    @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 校验验证码
        if("abcd".equalsIgnoreCase(code)) {
//        验证码正确
//            3 验证用户名是否存在
            if(userService.existsUsername(username)) {
//                用户名不可用
                System.out.println("用户名不可用");
//                跳转回注册页面
                req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
            } else {
//                用户名可用
//                保存注册信息
                userService.registUser(new User(null,username,password,email));
//                跳转到注册成功页面
                req.getRequestDispatcher("/pages/user/regist_success.html").forward(req,resp);
            }
        } else {
            //验证码错误
            System.out.println("验证码错误");
//            跳回注册页面
            req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
        }
    }
}

在web.xml中配置 RegistServlet

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

设置注册页面的数据提交地址(采用base+相对地址的方式) 

9、使用客户端登陆账户功能的实现

编写LoginServlet

package web;

import service.UserService;
import 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();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1 获取请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        // 2 调用UserService业务查询
        if(userService.login(username,password) == null) {
            // 返回值为null,登陆失败
            System.out.println("登陆失败!");
            // 跳转回登录页面
            req.getRequestDispatcher("/pages/user/login.html").forward(req,resp);
        } else {
            // 返回值不为null,登陆成功
            // 跳转到登陆成功页面
            req.getRequestDispatcher("/pages/user/login_success.html").forward(req,resp);
        }
    }
}

在web.xml中配置LoginServlet

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

设置注册页面的数据提交地址(采用base+相对地址的方式)

 


注:本文章所含内容来源于尚硅谷教育,仅供学习参考使用。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Tips and Tricks Internet Development Index -------------------------------------------------------------------------------- As with any type of programming, writing bug-free, efficient scripts that meet your expectations takes a bit of work. The following sections provide some tips and hints to make that work take less time and go more smoothly. Checking the Internet Explorer Version Number Canceling a Button Click Preventing a Document From Being Cached Using Objects Replacing Custom Controls with DHTML Checking the Internet Explorer Version Number You should always check for the type and version of the client browser, so that your content degrades gracefully if the client browser does not support features on your Web site. The easiest way to identify a browser and its characteristics (browser code name, version number, language, etc.) in script is through the Dynamic HTML (DHTML)?A HREF="objects/obj_navigator.html">navigator object. You can also access this object and its properties in C++ applications through the IOmNavigator interface. The userAgent property of the navigator object returns a string that includes the browser and browser version. The following example Microsoft® JScript® function runs on most browsers and returns the version number for any Microsoft Internet Explorer browser and zero for all other browsers. SHOWExample function msieversion() // Return Microsoft Internet Explorer (major) version number, or 0 for others. // This function works by finding the "MSIE " string and extracting the version number // following the space, up to the semicolon { var ua = window.navigator.userAgent var msie = ua.indexOf ( "MSIE " ) if ( msie > 0 ) // is Microsoft Internet Explorer; return version number return parseFloat ( ua.substring ( msie+5, ua.indexOf ( ";", msie ) ) ) else return 0 // is other browser } When checking browser version numbers, always check for version numbers greater than or equal to a target version. In this way, your Web site will be be compatible with future versions of the browser. For example, if you have designed your content for the latest version of Internet Explorer, use that version number as a minimum version number. Note Browsers often have several releases of a browser version. For example, 4.01, 5.0, 5.5 and 6.0b are all different versions of Internet Explorer. The 'b' in 6.0b represents a beta version of Internet Explorer 6. As of Internet Explorer 5, conditional comments are available as an alternative technique for detecting browser versions. Conditional comments have the advantage of not using a script block, which means that it is not always necessary to use scripting and DHTML when working with conditional comments. When no scripting is used in a Web page, no scripting engine needs to be loaded. Conditional comments are processed during the downloading and parsing phase, so only the content that is targeted for the browser loading the Web page is actually downloaded. Conditional comments can be combined freely with other browser detection techniques. For more information, see About Conditional Comments. Canceling a Button Click The following HTML example shows a common scripting mistake related to event handling and canceling the default action. SHOWExample <HTML> <HEAD><TITLE>Canceling the Default Action</TITLE> <SCRIPT LANGUAGE="JScript"> function askConfirm() { return window.confirm ("Choose OK to follow hyperlink, Cancel to not.") } </SCRIPT> <BODYonload="b3.onclick=askConfirm"> <!-- Try links with different hookups - should be canceled by "Cancel" to confirm dialog. --> <BR><A NAME=b1 HREF="http://www.microsoft.com" onclick="askConfirm()">1 Without return (won't work)</A> <BR><A NAME=b2 HREF="http://www.microsoft.com" onclick="return askConfirm()">2 With return (works)</A> <BR><A NAME=b3 HREF="http://www.microsoft.com">3 Function pointer (works)</A> </BODY> </HTML> The first a element in this example does not work properly. Without the return in the onclick燡Script expression, the browser interprets the function expression, throws away the resulting value, and leaves the default action unaffected. The other a elements correctly bind the return value to the event, hence the default action can be canceled when false is returned. Preventing a Document From Being Cached You can prevent a document from being cached by adding the following meta tag to the document. <META HTTP-EQUIV="Expires" CONTENT="0"> Preventing the document from being cached ensures that a fresh copy of the document will always be retrieved from the site, even during the user's current session, regardless of how the user has set the browser's caching options. This is useful if the content of the document changes frequently. Using Objects Objects are Microsoft® ActiveX® Controls or other similar components that provide custom capabilities and services for HTML documents. You can add a control to your document using the object element, and you can gain access to the capabilities and services of the control using its properties and methods from script. When using objects, be aware that DHTML extends every object by providing these additional properties: align classid code codeBase codeType data form height name object recordset type width If a control has properties with these same names, you will not be able to access the properties unless you preface the name with the object property. For example, assume that an ActiveX control is added to the document using the following: <OBJECT ID="MyControl" HEIGHT=100 WIDTH=200 CLASSID="clsid: ... "> </PARAM NAME="width" VALUE="400"> </OBJECT> In this example, there are two widths: an extended property set within the object element, and a property belonging to the control that is set using the param element. To access these from script, you use the following code. alert(MyControl.width); // this is Dynamic HTML's property; displays "200" alert(MyControl.object.width); // this is the object's property; displays "400" Replacing Custom Controls with DHTML DHTML provides everything you need to generate animated effects without resorting to custom controls. For example, consider the following script, which is a replacement for the Path control. SHOWExample var tickDuration; tickDuration = 50; var activeObjectCount; var activeObjects; var itemDeactivated; var tickGeneration; activeObjects = new Array(); activeObjectCount = 0; timerRefcount = 0; itemDeactivated = false; tickGeneration = 0; function initializePath(e) { e.waypointX = new Array(); e.waypointY = new Array(); e.duration = new Array(); } function addWaypoint(e, number, x, y, duration) { e.waypointX[number] = x; e.waypointY[number] = y; e.duration[number] = duration; } function compact() { var i, n, c; n = new Array(); c = 0; itemDeactivated = false; for (i=0; i<activeObjectCount; i++) { if (activeObjects[i].active == true) { n[c] = activeObjects[i]; c++; } } activeObjects = n; activeObjectCount = c; } function tick(generation) { if (generation < tickGeneration) { // alert("Error "+generation); return; } //alert("tick: "+generation); if (itemDeactivated) compact(); if (activeObjectCount == 0) { return; } else { for (i=0; i<activeObjectCount; i++) { moveElement(activeObjects[i]); } window.setTimeout("tick("+generation+");", tickDuration); } } function start(e) { if (itemDeactivated) compact(); activeObjects[activeObjectCount] = e; activeObjectCount++; if (activeObjectCount == 1) { tickGeneration++; tick(tickGeneration); } } function runWaypoint(e, startPoint, endPoint) { var startX, startY, endX, endY, duration; if (e.waypointX == null) return; startX = e.waypointX[startPoint]; startY = e.waypointY[startPoint]; endX = e.waypointX[endPoint]; endY = e.waypointY[endPoint]; duration = e.duration[endPoint]; e.ticks = duration / tickDuration; e.endPoint = endPoint; e.active = true; e.currTick = 0; e.dx = (endX - startX) / e.ticks; e.dy = (endY - startY) / e.ticks; e.style.posLeft = startX; e.style.posTop = startY; start(e); } function moveElement(e) { e.style.posLeft += e.dx; e.style.posTop += e.dy; e.currTick++; if (e.currTick > e.ticks) { e.active = false; itemDeactivated = true; if (e.onpathcomplete != null) { window.pathElement = e; e.onpathcomplete() } } } To use this script in your document, do the following: Load the script using the src attribute of the script element. Initialize the paths using the initializePath function. Set the way points using the addWaypoint function. Set the path-complete handlers using the runWaypoint function. The following sample document shows how this works. SHOWExample <html> <body> <div id=Item1 style="position: absolute; left: 0; top: 0;">Item1</div> <div id=Item2 style="position: absolute; left: 0; top: 0;">Item2</div> <div id=Item3 style="position: absolute; left: 0; top: 0;">Item3</div> <div id=Item4 style="position: absolute; left: 0; top: 0;">Item4</div> <div id=Item5 style="position: absolute; left: 0; top: 0;">Item5</div> <div id=Item6 style="position: absolute; left: 0; top: 0;">Item6</div> <input type=button value="Start" onclick="runWaypoint(Item1, 0, 1); runWaypoint(Item2, 0, 1);"> <div id=Debug>Generation</div> <script src="htmlpath.js"> </script> <script> // need to call initializePath on all objects that will be moved with this mechanism initializePath(Item1); initializePath(Item2); initializePath(Item3); initializePath(Item4); initializePath(Item5); initializePath(Item6); // the 0th waypoint is the initial position for waypoint #1 // syntax is item, waypoint, endx, endy, duration in msecs addWaypoint(Item1, 0, 0, 0, 0); addWaypoint(Item1, 1, 200, 200, 2000); addWaypoint(Item2, 0, 100, 100, 0); addWaypoint(Item2, 1, 400, 100, 4000); addWaypoint(Item3, 0, 400, 400, 0); addWaypoint(Item3, 1, 200, 100, 1000); addWaypoint(Item4, 0, 0, 0, 0); addWaypoint(Item4, 1, 200, 200, 2000); addWaypoint(Item5, 0, 100, 100, 0); addWaypoint(Item5, 1, 400, 100, 4000); addWaypoint(Item6, 0, 400, 400, 0); addWaypoint(Item6, 1, 200, 100, 1000); function endfunction() { // syntax for runWaypoint is Item, start point, end point runWaypoint(Item3, 0, 1); runWaypoint(Item4, 0, 1); runWaypoint(Item5, 0, 1); runWaypoint(Item6, 0, 1); } function endfunction2() { runWaypoint(Item1, 0, 1); } Item1.onpathcomplete = endfunction; Item6.onpathcomplete = endfunction2; </script> </body> </html> Show Me

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值