天天看點

Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

原文位址: http://www.work100.net/training/monolithic-frameworks-example.html 更多教程: 光束雲 - 免費課程

綜合執行個體

請參照如上

章節導航

進行閱讀

1.概述

本節将把「

Java單體應用

」課程做一個階段性的總結,通過一個綜合的案例将所學知識完整實踐一下。

我們後續階段的課程還有:

為了後續課程的連續性,我們的

綜合執行個體

将搭建一個簡單的

IoT管理背景

項目

iot-admin

,實作使用者的登入功能。

學習的過程要跟着練習并做好筆記!

2.建立項目

2.1.建構項目結構

建立項目檔案夾

通過

IntelliJ IDEA

打開前述章節的項目結構,新增一個項目檔案夾

iot-admin

建立

POM

添加一個

pom.xml

檔案,檔案内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.work100.training.stage2</groupId>
    <artifactId>iot-admin</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>      
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>
</project>           

然後将

pom.xml

托管到

Maven

完善Maven結構

完善下表的目錄結構:

目錄或檔案 說明
pom.xml POM檔案
src/main/java 源碼檔案夾
src/main/resources 資源檔案夾
src/main/webapp 網站檔案夾
src/main/webapp/WEB-INF 網站配置檔案夾
src/main/webapp/WEB-INF/web.xml 網站配置檔案
src/test/java 測試源碼檔案夾

項目結構如下圖:

Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

完善

src/main/webapp/WEB-INF/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">

</web-app>           

完善項目架構

結合三層架構及MVC架構,在

src/main/java

下建構項目的類包結構,如下表:

類包
net.work100.training.stage2.iot.admin 項目總的類包
net.work100.training.stage2.iot.admin.dao 資料通路層
net.work100.training.stage2.iot.admin.service 服務層
net.work100.training.stage2.iot.admin.web Web層
Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

配置 Spring 和 Log4j

src/main/resources

下添加

spring-context.xml

log4j.properties

檔案:

spring-context.xml

代碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>           

log4j.properties

log4j.rootLogger=INFO, console, file

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d %p [%c] - %m%n

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=logs/log.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.MaxFileSize=1024KB
log4j.appender.A3.MaxBackupIndex=10
log4j.appender.file.layout.ConversionPattern=%d %p [%c] - %m%n           

建構前端架構結構

參照

Bootstrap - 環境搭建 - 執行個體

中的步驟建構

Bootstrap

的目錄結構:

目錄
src/main/webapp/assets/ 靜态資源檔案目錄
src/main/webapp/assets/css/ 自定義樣式
src/main/webapp/assets/images/ 自定義圖檔
src/main/webapp/assets/js/ 自定義JS
src/main/webapp/assets/plugins/ 插件
src/main/webapp/assets/plugins/bootstrap/ Bootstrap插件
src/main/webapp/assets/plugins/bootstrap/css/ Bootstrap 樣式表檔案
src/main/webapp/assets/plugins/bootstrap/font-awesome/ 第三方字型
src/main/webapp/assets/plugins/bootstrap/js/ Bootstrap JS檔案
src/main/webapp/assets/plugins/bootstrap/jquery-3.4.1.min.js jQuery

src/main/webapp

下建立

index.jsp

檔案,代碼如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>IoT-Admin</title>
</head>
<body>
    Hello IoT-Admin
</body>
</html>           
Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

配置 Tomcat

參考

架構模式 - 實踐練習

中所述的

Tomcat

配置方式将運作環境配好,并運作驗證效果:

Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

3.使用AdminLTE模闆

3.1.下載下傳 AdminLTE

AdminLTE

是一個基于

Bootstrap

的後端模闆引擎,最新版本基于

Bootstrap 4

建構,高度可定制且易于使用,适合從小型移動裝置到大型桌上型電腦的多種螢幕分辨率。

官網位址為

https://adminlte.io/ https://adminlte.io/

,AdminLTE為開源軟體,可以前往

Github

擷取源碼。

本執行個體将使用

AdminLTE-3.0.2

版本進行示範,源碼包已經上傳至QQ群,請在

門戶首頁

下方加入

QQ群

擷取。

AdminLTE

下載下傳後解壓縮,檔案夾結構如下:

Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

将目錄下的檔案

index.html

用浏覽器打開運作,效果如下:

Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

請在使用

AdminLTE

架構前詳細浏覽各頁面的展示效果,并參照

HTML

源碼了解

AdminLTE

的使用方法。

3.2.重構項目

因為

AdminLTE-3.0.2

是基于

Bootstrap 4

建構的,是以接下來我們重構我們的項目。

首先,删除項目中的如下目錄:

  • src/main/webapp/assets/plugins

  • src/main/webapp/assets/css

  • src/main/webapp/assets/images

  • src/main/webapp/assets/js

然後,将

AdminLTE-3.0.2

下的檔案夾複制到項目中,對應位置為:

AdminLTE-3.0.2

項目中目錄
AdminLTE-3.0.2/plugins src/main/webapp/assets/plugins
AdminLTE-3.0.2/dist/css src/main/webapp/assets/css
AdminLTE-3.0.2/dist/images src/main/webapp/assets/images
AdminLTE-3.0.2/dist/js src/main/webapp/assets/js

重構後的目錄結構為:

Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

4.建立登入頁

我們參照

AdminLTE-3.0.2/pages/examples/login.html

源碼示例建構一個

iot-amdin

項目的登入頁。

重構

index.jsp

頁面,代碼如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>IoT-Admin</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Font Awesome -->
    <link rel="stylesheet" href="assets/plugins/fontawesome-free/css/all.min.css">
    <!-- icheck bootstrap -->
    <link rel="stylesheet" href="assets/plugins/icheck-bootstrap/icheck-bootstrap.min.css">
    <!-- Theme style -->
    <link rel="stylesheet" href="assets/css/adminlte.min.css">
</head>
<body class="hold-transition login-page">
<div class="login-box">
    <div class="login-logo">
        IoT-Admin 登入
    </div>
    <!-- /.login-logo -->
    <div class="card">
        <div class="card-body login-card-body">
            <p class="login-box-msg">請輸入ID和密碼登入</p>

            <form action="/login" method="post">
                <div class="input-group mb-3">
                    <input name="loginId" type="text" class="form-control" placeholder="登入ID">
                    <div class="input-group-append">
                        <div class="input-group-text">
                            <span class="fas fa-user"></span>
                        </div>
                    </div>
                </div>
                <div class="input-group mb-3">
                    <input name="loginPwd" type="password" class="form-control" placeholder="登入密碼">
                    <div class="input-group-append">
                        <div class="input-group-text">
                            <span class="fas fa-lock"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-8">
                        <div class="icheck-primary">
                            <input type="checkbox" id="remember">
                            <label for="remember">
                                記住我
                            </label>
                        </div>
                    </div>
                    <!-- /.col -->
                    <div class="col-4">
                        <button type="submit" class="btn btn-primary btn-block">登入</button>
                    </div>
                    <!-- /.col -->
                </div>
            </form>
        </div>
        <!-- /.login-card-body -->
    </div>
</div>
<!-- /.login-box -->

<!-- jQuery -->
<script src="assets/plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="assets/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="assets/js/adminlte.min.js"></script>

</body>
</html>           

運作

Tomcat

,啟動項目,效果如下:

Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

5.登入功能實作

後端代碼實作和

章節所述方式類似,我們将其實作代碼進行改造。

5.1.建立 User 類

在包

net.work100.training.stage2.iot.admin

下建立一個包

entity

,然後在其下新增一個

User

User.java

檔案代碼如下:

package net.work100.training.stage2.iot.admin.entity;

import java.io.Serializable;

/**
 * <p>Title: User</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 13:21
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public class User implements Serializable {
    private String userName;
    private String loginId;
    private String loginPwd;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getLoginId() {
        return loginId;
    }

    public void setLoginId(String loginId) {
        this.loginId = loginId;
    }

    public String getLoginPwd() {
        return loginPwd;
    }

    public void setLoginPwd(String loginPwd) {
        this.loginPwd = loginPwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", loginId='" + loginId + '\'' +
                '}';
    }
}           

5.2.建立 UserDao 接口及其實作 UserDaoImpl

net.work100.training.stage2.iot.admin.dao

下建立一個接口

UserDao

UserDao.java

package net.work100.training.stage2.iot.admin.dao;

import net.work100.training.stage2.iot.admin.entity.User;

/**
 * <p>Title: UserDao</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 13:16
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public interface UserDao {
    /**
     * 根據ID及密碼擷取使用者資訊
     *
     * @param loginId  登入ID
     * @param loginPwd 登入密碼
     * @return
     */
    User getUser(String loginId, String loginPwd);
}           

net.work100.training.stage2.iot.admin.dao

下新增一個類包

impl

,然後在

impl

包下建立一個類

UserDaoImpl

UserDaoImpl.java

package net.work100.training.stage2.iot.admin.dao.impl;

import net.work100.training.stage2.iot.admin.dao.UserDao;
import net.work100.training.stage2.iot.admin.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>Title: UserDaoImpl</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 13:23
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public class UserDaoImpl implements UserDao {

    private static final Logger logger = LoggerFactory.getLogger(UserDaoImpl.class);

    public User getUser(String loginId, String loginPwd) {
        logger.debug("調用方法 getUser(loginId:{}, loginPwd:{})", loginId, loginPwd);

        // 根據 loginId 查詢出使用者資訊
        User user = getUserByLoginId(loginId);
        if (user != null) {
            // 驗證 loginPwd 是否正确(區分大小寫)
            if (user.getLoginPwd().equals(loginPwd)) {
                return user;
            }
        }
        return null;
    }


    /**
     * 擷取模拟的使用者資料
     *
     * @param loginId 登入ID
     * @return
     */
    private User getUserByLoginId(String loginId) {
        // 模拟 DB 存在的使用者資料
        User dbUser = new User();
        dbUser.setUserName("Xiaojun");
        dbUser.setLoginId("admin");
        dbUser.setLoginPwd("admin");

        // 判斷是否存在 loginId 的使用者(忽略大小寫)
        if (dbUser.getLoginId().equalsIgnoreCase(loginId)) {
            logger.info("比對上使用者:{}", dbUser);
            return dbUser;
        }
        logger.warn("未比對任何使用者,将傳回 null");
        return null;
    }
}           

5.3.建立 UserService 接口及其實作 UserServiceImpl

net.work100.training.stage2.iot.admin.service

UserService

UserService.java

package net.work100.training.stage2.iot.admin.service;

import net.work100.training.stage2.iot.admin.entity.User;

/**
 * <p>Title: UserService</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 13:25
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public interface UserService {
    /**
     * 登入驗證
     *
     * @param loginId  登入ID
     * @param loginPwd 登入密碼
     * @return
     */
    User login(String loginId, String loginPwd);
}           

net.work100.training.stage2.iot.admin.service

impl

impl

UserServiceImpl

UserServiceImpl.java

package net.work100.training.stage2.iot.admin.service.impl;

import net.work100.training.stage2.iot.admin.dao.UserDao;
import net.work100.training.stage2.iot.admin.dao.impl.UserDaoImpl;
import net.work100.training.stage2.iot.admin.entity.User;
import net.work100.training.stage2.iot.admin.service.UserService;

/**
 * <p>Title: UserServiceImpl</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 13:26
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImpl();

    public User login(String loginId, String loginPwd) {
        return userDao.getUser(loginId, loginPwd);
    }
}           

5.4.建立 LoginController

實作 Servlet

net.work100.training.stage2.iot.admin.web

controller

controller

LoginController

LoginController.java

package net.work100.training.stage2.iot.admin.web.controller;

import net.work100.training.stage2.iot.admin.entity.User;
import net.work100.training.stage2.iot.admin.service.UserService;
import net.work100.training.stage2.iot.admin.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;

/**
 * <p>Title: LoginController</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 13:28
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public class LoginController extends HttpServlet {

    private UserService userService = new UserServiceImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        User user = userService.login("admin", "admin");
        System.out.println("--------------doGet test(begin)-----------------");
        System.out.println(user);
        System.out.println("--------------doGet test(end)-----------------");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String loginId = req.getParameter("loginId");
        String loginPwd = req.getParameter("loginPwd");

        User user = userService.login(loginId, loginPwd);

        // 登入成功
        if (user != null) {
            // 重定向到首頁
            resp.sendRedirect("/main.jsp");
        }
        // 登入失敗
        else {
            // 跳轉回登入頁
            req.getRequestDispatcher("/index.jsp").forward(req, resp);
        }
    }
}           

配置 Servlet 映射

修改

src/main/webapp/WEB-INF/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>loginController</servlet-name>
        <servlet-class>net.work100.training.stage2.iot.admin.web.controller.LoginController</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>loginController</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
</web-app>           

建立登入成功後展示頁面 main.jsp

為了模拟登入驗證後的效果,我們在檔案夾

src/main/webapp/

下建立檔案

main.jsp

,登入成功後将跳轉至此頁面,代碼如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首頁</title>
</head>
<body>
這裡是首頁
</body>
</html>           

5.5.運作

啟動

Tomcat

進行登入驗證,表單輸入以下正确的登入資料:

名稱
使用者名 admin
密碼

頁面将跳轉至

main.jsp

,如下圖:

Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

輸入錯誤登入資料時,重新傳回到登入頁。

5.6.使用 Spring IoC

建立 SpringContext 類

建立一個類包

net.work100.training.stage2.iot.admin.commons.context

,然後在其下建立

SpringContext

SpringContext.java

package net.work100.training.stage2.iot.admin.commons.context;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * <p>Title: SpringContext</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 14:31
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public final class SpringContext {

    public Object getBean(String beanId) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        return context.getBean(beanId);
    }

}           

配置 spring-context.xml

src/main/resources/spring-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- DAO -->
    <bean id="userDao" class="net.work100.training.stage2.iot.admin.dao.impl.UserDaoImpl" />

    <!-- Service -->
    <bean id="userService" class="net.work100.training.stage2.iot.admin.service.impl.UserServiceImpl" />
</beans>           

修改 UserServiceImpl

UserServiceImpl.java

代碼,如下:

package net.work100.training.stage2.iot.admin.service.impl;

import net.work100.training.stage2.iot.admin.commons.context.SpringContext;
import net.work100.training.stage2.iot.admin.dao.UserDao;
import net.work100.training.stage2.iot.admin.entity.User;
import net.work100.training.stage2.iot.admin.service.UserService;

/**
 * <p>Title: UserServiceImpl</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 13:26
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public class UserServiceImpl implements UserService {

    private SpringContext context = new SpringContext();

    public User login(String loginId, String loginPwd) {
        UserDao userDao = (UserDao) context.getBean("userDao");
        return userDao.getUser(loginId, loginPwd);
    }
}           

修改 LoginController

LoginController.java

package net.work100.training.stage2.iot.admin.web.controller;

import net.work100.training.stage2.iot.admin.commons.context.SpringContext;
import net.work100.training.stage2.iot.admin.entity.User;
import net.work100.training.stage2.iot.admin.service.UserService;

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

/**
 * <p>Title: LoginController</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 13:28
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public class LoginController extends HttpServlet {

    private SpringContext context = new SpringContext();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        UserService userService = (UserService) context.getBean("userService");
        User user = userService.login("admin", "admin");
        System.out.println("--------------doGet test(begin)-----------------");
        System.out.println(user);
        System.out.println("--------------doGet test(end)-----------------");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        UserService userService = (UserService) context.getBean("userService");
        String loginId = req.getParameter("loginId");
        String loginPwd = req.getParameter("loginPwd");

        User user = userService.login(loginId, loginPwd);

        // 登入成功
        if (user != null) {
            // 重定向到首頁
            resp.sendRedirect("/main.jsp");
        }
        // 登入失敗
        else {
            // 跳轉回登入頁
            req.getRequestDispatcher("/index.jsp").forward(req, resp);
        }
    }
}           

重新運作

重新開機

Tomcat

驗證運作效果。

6.提升使用者體驗

當使用者輸入錯誤的ID或密碼時驗證會失敗,然後頁面會跳轉回登入頁。

從使用者體驗角度考慮,需要給使用者一個

提示資訊

,告知其登入驗證失敗了,下面我們來實作這個功能。

6.1.改造 LoginController

登入驗證失敗後增加傳回錯誤資訊

req.setAttribute("message", "登入ID或登入密碼錯誤");

,完整代碼如下:

package net.work100.training.stage2.iot.admin.web.controller;

import net.work100.training.stage2.iot.admin.commons.context.SpringContext;
import net.work100.training.stage2.iot.admin.entity.User;
import net.work100.training.stage2.iot.admin.service.UserService;

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

/**
 * <p>Title: LoginController</p>
 * <p>Description: </p>
 * <p>Url: http://www.work100.net/training/monolithic-frameworks-example.html</p>
 *
 * @author liuxiaojun
 * @date 2020-02-13 13:28
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-13   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public class LoginController extends HttpServlet {

    private SpringContext context = new SpringContext();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        UserService userService = (UserService) context.getBean("userService");
        User user = userService.login("admin", "admin");
        System.out.println("--------------doGet test(begin)-----------------");
        System.out.println(user);
        System.out.println("--------------doGet test(end)-----------------");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        UserService userService = (UserService) context.getBean("userService");
        String loginId = req.getParameter("loginId");
        String loginPwd = req.getParameter("loginPwd");

        User user = userService.login(loginId, loginPwd);

        // 登入成功
        if (user != null) {
            // 重定向到首頁
            resp.sendRedirect("/main.jsp");
        }
        // 登入失敗
        else {
            // 跳轉回登入頁
            req.setAttribute("message", "登入ID或登入密碼錯誤");
            req.getRequestDispatcher("/index.jsp").forward(req, resp);
        }
    }
}
           

6.2.改造 index.jsp

引入 JSTL 依賴

這裡我們會用到 JSTL 表達式,是以需要先在

pom.xml

檔案中引入依賴:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>           

增加 taglib 指令

index.jsp

檔案頭增加如下代碼:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>           

增加錯誤提示

index.jsp

檔案的

form

表單上方增加如下代碼:

<c:if test="${message != null}">
    <div class="alert alert-danger alert-dismissible">
       <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
          ${message}
    </div>
</c:if>           

完整 index.jsp 檔案代碼如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>IoT-Admin</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Font Awesome -->
    <link rel="stylesheet" href="assets/plugins/fontawesome-free/css/all.min.css">
    <!-- icheck bootstrap -->
    <link rel="stylesheet" href="assets/plugins/icheck-bootstrap/icheck-bootstrap.min.css">
    <!-- Theme style -->
    <link rel="stylesheet" href="assets/css/adminlte.min.css">
</head>
<body class="hold-transition login-page">
<div class="login-box">
    <div class="login-logo">
        IoT-Admin 登入
    </div>
    <!-- /.login-logo -->
    <div class="card">
        <div class="card-body login-card-body">
            <p class="login-box-msg">請輸入ID和密碼登入</p>
            <c:if test="${message != null}">
                <div class="alert alert-danger alert-dismissible">
                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                        ${message}
                </div>
            </c:if>
            <form action="/login" method="post">
                <div class="input-group mb-3">
                    <input name="loginId" type="text" class="form-control" placeholder="登入ID">
                    <div class="input-group-append">
                        <div class="input-group-text">
                            <span class="fas fa-user"></span>
                        </div>
                    </div>
                </div>
                <div class="input-group mb-3">
                    <input name="loginPwd" type="password" class="form-control" placeholder="登入密碼">
                    <div class="input-group-append">
                        <div class="input-group-text">
                            <span class="fas fa-lock"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-8">
                        <div class="icheck-primary">
                            <input type="checkbox" id="remember">
                            <label for="remember">
                                記住我
                            </label>
                        </div>
                    </div>
                    <!-- /.col -->
                    <div class="col-4">
                        <button type="submit" class="btn btn-primary btn-block">登入</button>
                    </div>
                    <!-- /.col -->
                </div>
            </form>
        </div>
        <!-- /.login-card-body -->
    </div>
</div>
<!-- /.login-box -->

<!-- jQuery -->
<script src="assets/plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="assets/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- AdminLTE App -->
<script src="assets/js/adminlte.min.js"></script>

</body>
</html>           

6.3.驗證效果

Tomcat

,輸入錯誤的登入資料,頁面效果如下:

Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體

7.執行個體源碼

執行個體源碼已經托管到如下位址:

上一篇:

Log4j

下一篇:

Spring Web
如果對課程内容感興趣,可以掃碼關注我們的

公衆号

QQ群

,及時關注我們的課程更新
Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體
Java單體應用 - 常用架構 - 05.綜合執行個體(iot-admin)綜合執行個體