5分鐘教你用java做最簡單的登錄系統

目錄

      前言

一. 項目需求和分析

二. 準備工作資源

三. 編寫邏輯代碼 

四. 測試及運行 

五. 反思總結 


前言

JavaWeb學了有一段時間了,學到了很多東西,但學歸學,它是不是真正成爲自己的了還真不好說。俗話說得好,如果你能用自己的語言給別人把一個晦澀難懂的東西講清楚,那你就真的會了。故作此文,教大家搭建一個非常基礎的登錄系統,順便鞏固一下這段時間學的重要知識。 

 

一.項目需求和分析

1.用戶登錄:

1. 編寫login.html登錄頁面:username $ password 兩個輸入框

2. 使用Druid數據庫連接池技術,操作mysql,db1數據庫中user表

3. 使用JdbcTemplate技術封裝JDBC

4. 登錄成功跳轉到SuccessServlet展示:登錄成功,username,歡迎你

5. 登錄失敗跳轉到FailServlet展示:登錄失敗,用戶名或密碼錯誤

2.需求分析:     

 

二.  準備工作資源

1.工具:

* idea企業版(因爲企業版才集成的有Tomcat服務器)

* 各種依賴jar包和驅動:

        鏈接:https://pan.baidu.com/s/1fKEaSDFllKVUR-QasSgA5g 提取碼:lx4o 

* Mysql5.7:Mysql 8可能會遇到一些問題,版本不一樣有些規則會修改,所以儘量按我的環境來,我都踩過這些坑

* jdk1.8或以上:如果提示有無效版本,你可以換高版本的jdk,我還有個jdk14換着用的

* Navicat for Mysql:根據自己喜好,可有可無,也可以用其他的可視化數據庫操作軟件

2.創建項目模塊

 選擇new->Module->Java Enterprise.

配置如下:只需要改這三項 :

                 JavaEE version改成Java EE 7

                 勾選Web Application,

                 取消Create web.xml的勾選就可以了,其他不用管,Next

 位置僅供參考

創建完成後先在web文件夾下創建倆文件夾用來存儲依賴jar包和驅動包

這些依賴包並不能直接使用,我們要右鍵點擊lib文件夾,或者我們把這些包全部選中再右鍵,然後add as library->Level選Module Library,這樣這些jar包就生效了。啥,不知道add as library是啥東西,點右邊吧 ——> 傳送門,帶你飛~ 

根據需求分析我們了db1數據庫並創建user表,我添加了一條數據用於後面驗證demo是否成功。

爲了使用 druid數據庫連接池技術 來操作數據庫,我們引入druid.properties來配置數據庫,放在src目錄下即可。

(鏈接:https://pan.baidu.com/s/14gU_aEYped66A0wm_P4zJQ 提取碼:v0se)

準備工作搞定~ 

三. 編寫邏輯代碼 

 1.編寫登錄頁面(login.html)

明人不說暗話,咱也不會,咋也不整那麼多花裏胡哨的,有那個意思就行了。

放到web目錄下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
<!--    action指定的路徑爲:虛擬目錄+資源路徑-->
    <form action="/login_demo2/loginServlet" method="post">
        用戶名:<input type="text" name="username"><br>
        密碼:<input type="password" name="password"><br>

        <input type="submit" value="登錄">
    </form>
</body>
</html>

 2.編寫用戶實體類(User)

這裏面裝的都是用戶的各個屬性。爲啥要這樣寫呢?單獨把用戶封裝起來,然後用戶操作數據庫等操作單獨寫接口,這樣才能高內聚,低耦合的效果。

放到src.cn.it.np.domain目錄下(給你個完整項目路徑,你看看就知道了)

package cn.it.np.domain;

/**
 * 用戶的實體類(JavaBean)
 */
public class User {
    //用戶id
    private int id;
    //用戶名
    private String username;
    //密碼
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int 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 + '\'' +
                '}';
    }
}

3.編寫JDBC工具類(JDBCUtils)

由於用到了Druid和Template,爲了封裝和簡化Mysql的操作,我們一般都會編寫一個JDBC工具類,讓我們更方便的獲取連接池對象或Connection對象 ,用到了Druid的知識。

什麼?你說你不知道什麼叫Druid!點右邊帶你坐飛機 ——> 帶你裝b,帶你飛

放到src.cn.it.np.util目錄下

package cn.it.np.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具類 使用Druid
 */
public class JDBCUtils {

    private static DataSource ds;

    static {
        try {
        //1.加載配置文件
        Properties pro = new Properties();
        //使用ClassLoader加載配置文件,獲取字節輸入流
        InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);

        //2.初始化連接池對象
        ds = DruidDataSourceFactory.createDataSource(pro);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //獲取連接池對象
    public static DataSource getDataSource(){
        return ds;
    }

    //獲取連接Connection對象
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
}

4.編寫數據庫接口類(UserDao)

百度Dao如下:

DAO(Data Access Object)是一個數據訪問接口,數據訪問:顧名思義就是與數據庫打交道。夾在業務邏輯與數據庫資源中間。

它負責和數據庫打交道,我們通過它來將用戶實體類User和數據庫連接起來實現判斷用戶賬號密碼是否在數據庫中的操作。這裏主要用到了Spring框架裏的 JdbcTemplate,同時還用到了工具類JDBCUtils。什麼?你說你不知道Template?快點擊這裏吧!——> 帶你飛 

放到src.cn.it.np.dao目錄下

package cn.it.np.dao;

import cn.it.np.domain.User;
import cn.it.np.util.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * 操作數據庫中User表的類
 */
public class UserDao {
    //聲明JDBCTemplate對象共用
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());

    /**
     * 登錄方法
     * @param loginUser 只有用戶名和密碼
     * @return user包含用戶所有信息
     */
    public User login(User loginUser){
        try {
            //1.編寫sql
            String sql = "select * from user where username = ? and password = ?";

            //2.調用template的query方法
//            User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), loginUser.getUsername(), loginUser.getPassword());
            User user = template.queryForObject(sql,
                    new BeanPropertyRowMapper<User>(User.class), loginUser.getUsername(), loginUser.getPassword());

            return user;
        } catch (DataAccessException e) {
            e.printStackTrace();
            return null;
        }
    }
}

5.編寫業務邏輯類(loginServlet、successServlet、failServlet) 

判斷用戶是否成功登陸及後續的跳轉操作,用到了Servlet的請求與轉發操作。

啥?你說你不知道?快飛吧 ——> 好,你飛了

loginServlet

package web.servlet;

import cn.it.np.dao.UserDao;
import cn.it.np.domain.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.設置字符編碼
        req.setCharacterEncoding("utf-8");
        //2.接收user數據
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        //3.封裝成User對象
        User loginuser = new User();
        loginuser.setUsername(username);
        loginuser.setPassword(password);

        //4.判斷與轉發
        UserDao dao = new UserDao();
        User user = dao.login(loginuser);

        if(user != null){
            //登錄成功
            //存儲共享數據
            req.setAttribute("user",user);
            req.getRequestDispatcher("/successServlet").forward(req,resp);
        }else{
            //登錄失敗
            req.getRequestDispatcher("/failServlet").forward(req,resp);
        }

    }

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

successServlet

package web.servlet;

import cn.it.np.domain.User;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/successServlet")
public class successServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.獲取request域中共享的user數據
        User user = (User)request.getAttribute("user");

        //2.頁面打印
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("歡迎" + user.getUsername() + "登錄成功!");
    }
}

 failServlet

package web.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/failServlet")
public class failServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //頁面打印
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("登錄失敗");
    }
}

6.這中間我們還可以穿插單元檢測比如我們寫完UserDao這個類的時候,我們如何檢測其是否正確,這時候就用到了單元檢測。

只要在要檢測部分前面加上註解 @Test 即可(說到這裏可能有些小小白會無法運行,那肯定是你沒有導包。idea很智能,點一下註解,alt+enter鍵回車就能自動導包了)

package cn.it.np.test;

import cn.it.np.dao.UserDao;
import cn.it.np.domain.User;
import org.junit.Test;


public class UserDao_Test {
    @Test
    public void testLogin(){
        User loginuser = new User();
        loginuser.setUsername("zhangsan");
        loginuser.setPassword("666");

        UserDao dao = new UserDao();
        User user = dao.login(loginuser);
        System.out.println(user);
    }
}

 然後點擊左側的播放按鈕,如果成功輸出user信息則說明UserDao模塊是ok的。

 至此,項目基本完成,看看能不能運行吧!

四. 測試及運行 

這裏要注意檢查你的login.html頁面,action必須指定爲:虛擬目錄+資源路徑。這裏我Tomcat部署項目時設置的虛擬目錄爲/login_demo2.

進入登陸頁面 

 

登陸失敗時: 

登陸成功時 

五. 反思總結 

 通過本次項目的學習和演示,我總結出以下一個登陸模塊編寫流程:

前端界面(login.html)-> 用戶實體類(User)-> 數據庫接口類(UserDao) -> 中間可穿插單元測試類(UserDao_Test等測試類) -> 用到什麼工具類就寫什麼工具類(JDBCUtils)-> 邏輯類(按業務邏輯寫完剩下的常規類)

經過多次bug的折磨,我明白要經常進行unit測試,要養成好習慣,希望大家能一起進步,成爲大牛牛!


更新

        和之前的代碼不完全一致,是重新寫的,要注意的是這裏沒用UserDao寫全,爲了快速搭建我就寫死了。你們需要可以用UserDao接口,方法和上面是一樣的new User對象來接收。用了jsp簡化書寫,加入驗證碼驗證功能。

checkCodeServlet 

package cn.it.np;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet("/checkCodeServlet")
public class checkCodeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.定義圖片寬高
        int width = 100;
        int height = 50;

        //2.創建一個對象,在內存中存圖片
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

        //3.美化圖片,掏出畫筆開始搞
        Graphics g = image.getGraphics();

        //4.先給圖片填個色
        g.setColor(Color.orange);
        g.fillRect(0,0,width,height);

        //5.在圖片的邊緣畫一畫使圖片效果更好
        g.setColor(Color.blue);
        g.drawRect(0,0,width-1,height-1);

        //7.製造干擾條紋
        Random ran = new Random();
        g.setColor(Color.gray);
        for(int i=0;i<8;i++){
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);
            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1,y1,x2,y2);
        }

        //6.畫驗證碼字符
        StringBuilder sb = new StringBuilder();
        g.setColor(Color.black);
        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

        for(int i=1;i<=4;i++){
            //創造不超過str長度的隨機下標
            int index = ran.nextInt(str.length());
            //獲得該隨機下標對應的字符
            char ch = str.charAt(index);
            sb.append(ch);
            //在適當的位置畫字符
            g.drawString(ch + "",width/5*i,height/2);
        }
        //用session存儲驗證碼字符
        String str_checkCode = sb.toString();
        HttpSession session = req.getSession();
        session.setAttribute("checkCode",str_checkCode);

        //將圖片輸出到屏幕上
        ImageIO.write(image,"jpg",resp.getOutputStream());

    }

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

loginServlet 

package cn.it.np;

import javax.imageio.ImageIO;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.獲取表單參數
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String checkCode = req.getParameter("checkCode");

        //2.判斷驗證碼和密碼是否正確
        //獲取驗證碼
        HttpSession session = req.getSession();
        String str_checkCode =(String) session.getAttribute("checkCode");
        //刪除session中存儲的驗證碼
        session.removeAttribute("checkCode");

        //驗證碼正確,判斷賬號密碼是否正確
        if(str_checkCode != null && checkCode.equalsIgnoreCase(str_checkCode)){
            //賬號密碼也正確
            if(username.equals("zhangsan") && password.equals("666")){//使用UserDao接口
                //用session存儲用戶信息並轉發到success.jsp頁面
                session.setAttribute("username",username);
                resp.sendRedirect(req.getContextPath() + "/success.jsp");
            }else{
                //賬號密碼不正確
                req.setAttribute("fail","用戶名或密碼錯誤!");
                req.getRequestDispatcher(req.getContextPath() + "/login.jsp").forward(req,resp);

            }
        }else{
            //驗證碼不正確,跳轉到login.jsp,提示驗證碼錯誤
            req.setAttribute("codeFail","驗證碼錯誤!");
            req.getRequestDispatcher(req.getContextPath() + "/login.jsp").forward(req,resp);
        }

    }

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

login.jsp

<%@ page import="java.awt.image.BufferedImage" %>
<%@ page import="java.awt.*" %>
<%@ page import="java.util.Random" %>
<%@ page import="javax.imageio.ImageIO" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
    <script>
        window.onload = function (ev) {
            document.getElementById("checkCode").onclick = function (ev1) {
                this.src = "/checkCodeServlet?time=" + new Date().getTime();
            }

        }
    </script>
    
    <style>
        div{
            color: red;
        }
    </style>
</head>
<body>
    <form action="/loginServlet" method="post">
        <table>
            <tr>
                <td>用戶名</td>
                <td><input type="text" name="username"></td>
            </tr>


            <tr>
                <td>密碼</td>
                <td><input type="password" name="password"></td>
            </tr>

            <tr>
                <td>驗證碼</td>
                <td><input type="text" name="checkCode"></td>
            </tr>

            <tr>
                <td colspan="2"><img src="/checkCodeServlet" id="checkCode"></td>
            </tr>

            <tr>
                <td colspan="2">
                    <input type="submit" value="登錄">
                </td>
            </tr>

        </table>
    </form>

    <div><%=request.getAttribute("fail") == null ? "" : request.getAttribute("fail")%></div>
    <div><%=request.getAttribute("codeFail") == null ? "" : request.getAttribute("codeFail")%></div>

</body>
</html>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
    <h1>歡迎你,<%=request.getSession().getAttribute("username")%>
</body></h1>

</html>

運行結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章