[Web development] implementation of login and registration function

Login and registration is a common function of the website. This article implements a small demo of this function according to the tutorial of dark horse programmer.
reference resources: https://www.bilibili.com/video/BV1Qf4y1T7Hx?p=109
maven file download: https://download.csdn.net/download/qq1198768105/79568473

Login function

Train of thought analysis

Login page design


See maven file for relevant front-end resource files.

Data table data establishment

Directly use the mysql database integrated with IDEA to establish data.
Set each user to have three values:
Primary key: id
User name: username (up to 20 characters, cannot be repeated)
Password: password (up to 32 bits)
Set up an account: zstar,123
Related sql statements:

create table tb_user(
    id int primary key auto_increment,
    username varchar(20) unique,
    password varchar(32)
);

insert into tb_user (username,password) values('zstar','123');

select * from tb_user;

Create entity class

On COM itheima. Create a User entity class under the POJO folder. The three attributes of the entity class correspond to the three values in the data table:

package com.itheima.pojo;

public class User {

    private Integer id;
    private String username;
    private String password;

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

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

Import driver

In the POM of the project XML import required drive coordinates

<dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
</dependencies>

Set mybatis configuration

Create mybatis config XML core configuration file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--Alias-->
    <typeAliases>
        <package name="com.itheima.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?useSSL=false&amp;useServerPrepStmts=true"/>
                <property name="username" value="root"/>
                <property name="password" value="zzz"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--scanning mapper-->
        <package name="com.itheima.mapper"/>
    </mappers>
</configuration>

Note: you need to set it according to your own database information
My database is called mybatis, which can be modified on the url
The database user name is root
The password is zzz
useSSL: turn off SSL secure connection for better performance
useServerPrepStmts: enable precompiling
&Equivalent to & (write directly and report an error)

Create UserMapper interface

In the configuration file of mapatis, set the scanning mapper to com itheima. mapper
On COM itheima. Create UserMapper interface under mapper package

package com.itheima.mapper;

import com.itheima.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {
    /**
     * Query user objects by user name and password
     * @param username
     * @param password
     * @return
     */
    @Select("select * from tb_user where username = #{username} and password = #{password}")
    User select(@Param("username") String username,@Param("password")  String password);
}

There are two main ways to implement this interface. The first is to create usermapper in the same folder XML file, which is associated with namespace in the file. The second method is directly applicable to the implementation of sql statements with annotations.
The second method is adopted here.

There are two ways to place placeholders for sql statements, one is #{}, and the other is ${}. The difference between the two is:
#When you execute SQL, replace the placeholder with {#}?, Parameter values will be set automatically in the future. The bottom layer uses PreparedStatement
${}: splicing SQL. The Statement is used at the bottom layer, and there will be SQL injection problems.
Therefore, to prevent SQL injection problems, use # no $.

@Function of Param annotation: it is used to pass parameters. It is the parameter of the method, which can correspond to the field name in SQL.

Modify login page

Modify loign html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>login</title>
    <link href="css/login.css" rel="stylesheet">
</head>

<body>
<div id="loginDiv">
    <form action="/request-demo/loginServlet" method="post" id="form">
        <h1 id="loginMsg">LOGIN IN</h1>
        <p>Username:<input id="username" name="username" type="text"></p>

        <p>Password:<input id="password" name="password" type="password"></p>

        <div id="subDiv">
            <input type="submit" class="button" value="login up">
            <input type="reset" class="button" value="reset">&nbsp;&nbsp;&nbsp;
            <a href="register.html">No account? Click Register</a>
        </div>
    </form>
</div>

</body>
</html>

The main modification here is that the id of username and password should be set so that they can be obtained by the following LoginServlet.

Write login Servlet

package com.itheima.web;

import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import com.itheima.util.SqlSessionFactoryUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. Receive user name and password
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        //2. Call MyBatis to complete the query
        //2.1 get SqlSessionFactory object
       /* String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);*/

        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
        //2.2 get SqlSession object
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //2.3 get Mapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //2.4 calling method
        User user = userMapper.select(username, password);
        //2.5 releasing resources
        sqlSession.close();


        //Get the character output stream and set the content type
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        //3. Judge that the user release is null
        if(user != null){
            // Login successful
            writer.write("Login successful");
        }else {
            // Login failed
            writer.write("Login failed");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

Note: in 2.1 obtaining SqlSessionFactory object, the same three lines of code are used for login and subsequent registration. If two servlets are obtained, they will be created repeatedly and consume more resources; Therefore, an optimization is made here to create a SqlSessionFactory tool class and use static code blocks to ensure that it is executed only once.

SqlSessionFactory tool class: SqlSessionFactoryUtils

package com.itheima.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class SqlSessionFactoryUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        //Static code blocks are executed automatically and only once as the class is loaded

        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}

functional testing

Start tomcat service using Maven Helper plug-in:

Enter the page and visit

http://localhost:8080/request-demo/login.html

Can access normally, submit data, submit data, and report errors if found:
Could not create connection to database server
Query reason: the database version and driver do not match
View my mysql version on the console: 8.0.28

In POM Modify mysql driver in XML:

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

Run again and the result is normal.

Registration function

Train of thought analysis

Registration page design


register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Welcome to register</title>
    <link href="css/register.css" rel="stylesheet">
</head>
<body>

<div class="form-div">
    <div class="reg-content">
        <h1>Welcome to register</h1>
        <span>Existing account?</span> <a href="login.html">Sign in</a>
    </div>
    <form id="reg-form" action="/request-demo/registerServlet" method="post">

        <table>

            <tr>
                <td>user name</td>
                <td class="inputs">
                    <input name="username" type="text" id="username">
                    <br>
                    <span id="username_err" class="err_msg" style="display: none">User names are not very popular</span>
                </td>

            </tr>

            <tr>
                <td>password</td>
                <td class="inputs">
                    <input name="password" type="password" id="password">
                    <br>
                    <span id="password_err" class="err_msg" style="display: none">Incorrect password format</span>
                </td>
            </tr>

        </table>

        <div class="buttons">
            <input value="Register" type="submit" id="reg_btn">
        </div>
        <br class="clear">
    </form>

</div>
</body>
</html>

Modify UserMapper

Add the functions of querying user names and adding users on the basis of the previous ones:

package com.itheima.mapper;

import com.itheima.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {


    /**
     * Query user objects by user name and password
     * @param username
     * @param password
     * @return
     */
    @Select("select * from tb_user where username = #{username} and password = #{password}")
    User select(@Param("username") String username,@Param("password")  String password);

    /**
     * Query user object by user name
     * @param username
     * @return
     */
    @Select("select * from tb_user where username = #{username}")
    User selectByUsername(String username);

    /**
     * Add user
     * @param user
     */
    @Insert("insert into tb_user values(null,#{username},#{password})")
    void add(User user);
}

Write registration Servlet

Similar to login, RegisterServlet:

package com.itheima.web;

import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import com.itheima.util.SqlSessionFactoryUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.InputStream;

@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. Receive user data
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        //Encapsulate user objects
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);

        //2. Call mapper to query the user object according to the user name
        //2.1 get SqlSessionFactory object
       /* String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);*/
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();

        //2.2 get SqlSession object
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //2.3 get Mapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        //2.4 calling method
        User u = userMapper.selectByUsername(username);

        //3. Judge that the user object is released as null
        if( u == null){
            // User name does not exist, add user
            userMapper.add(user);

            // Commit transaction
            sqlSession.commit();
            // Release resources
            sqlSession.close();
        }else {
            // If the user name exists, a prompt message will be given
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("User name already exists");
        }

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

functional testing

visit

http://localhost:8080/request-demo/register.html

After submitting the form, check the database, successfully input the new user data, and the test passes.

Keywords: Web Development MySQL Maven intellij-idea

Added by itpvision on Mon, 07 Feb 2022 08:08:38 +0200