使用springboot實現一個簡單的restful crud——03、前端頁面、管理員登陸(注銷)功能


前言

這一篇我們就先引入前端頁面和相關的靜態資源,再做一下管理員的登陸和注銷的功能,為后續在頁面上操作數據做一個基礎。

前端頁面

前端的頁面是我從網上找的一個基於Bootstrap 的dashboard模板,可以用來作為后台管理的界面,前端頁面代碼繁多,我只貼一些重要的,就不全部貼出來了。

引入靜態資源

<!-- Bootstrap core CSS -->
<!--公共資源通過webjars引入-->
<link href="/asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">

<!-- Custom styles for this template -->
<!--自定義資源通過普通方式引入-->
<link href="/asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet">

要使用th:href,要先倒入thymeleaf命名空間。

添加xmlns:th="http://www.thymeleaf.org"。idea就會出語法提示。

webjars:

    1. 將靜態資源版本化,更利於升級和維護。
    1. 剝離靜態資源,提高編譯速度和打包效率。
    1. 實現資源共享,有利於統一前端開發。

怎么使用webjars呢?

依賴

<!--通過webjar引入前端庫-->
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>4.0.0</version>
</dependency>

可以在官網快速找到各種常用前端庫的引用:https://www.webjars.org/

資源所在位置

項目External Libraries文件夾:


webjars映射規則

th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}"

所有/webjars/**的url 都去classpath:/META-INF/resources/webjars/找資源。


springboot資源映射規則

以"/**"訪問當前項目的任何資源都會首先去如下路徑尋找,這些路徑是靜態資源的文件夾:

classpath:/META-INF/resources/,

classpath:/resources/,

classpath:/static/,

classpath:/public/

ps: classpath src->main->resources文件夾

#可以在配置文件中修改靜態資源文件路徑
spring:
  resources:
    static-locations:

th:href="@{/asserts/css/signin.css}"

我的sign.css是放在classpath:/static/asserts/css文件夾下


禁止自動填充

現在很多瀏覽器都會把cookie信息自動填充到我們的表單中,我們如果想要禁止自動填充,怎么做呢?

<input name="username" autocompleted="off" type="text" class="form-control" placeholder="Username" th:placeholder="#{login.username}" required="" autofocus="">

<input name="password" autocomplete="new-password" autocompleted="off" type="password" class="form-control" th:placeholder="#{login.password}" placeholder="Password" required="">

在username中添加autocompleted="off"

在password中添加autocomplete="new-password" autocompleted="off"

擴展springmvc

在config包下新建MyMvcConfig類實現了WebMvcConfigurer接口,然后實現了addViewControllers方法。

package com.jotal.springboot08restfulcrud.config;

/*
* 不能使用@EnableWebMvc,使用了就是全面接管springmvc,自動配置就會失效
* 實現WebMvcConfigurer,來擴展springmvc的功能
* */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    //識圖適配器
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

        //登陸
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/login.html").setViewName("login");
    }

}

springboot已經幫我們自動配置好了springmvc,我們為什么還要擴展springmvc?

例如我們需要項目一啟動就跳轉到一個頁面,我們以往可能會寫一個Controller方法來跳轉,但是方法里沒有什么內容,這樣就顯得很浪費。這時候我們就可以addViewControllers中添加視圖適配規則。不僅僅是視圖適配,我們還可以擴展攔截器、國際化等,來豐富系統功能。這些將會在下面介紹到。

registry.addViewController("/").setViewName("login"); 這句話就定義了項目一啟動就跳轉login頁面。

/login和/login.html都會跳轉到login頁面。那么是怎么通過一個字符串“login”就會跳轉到login.html呢?是thymeleaf視圖解析器完成的。

thymeleaf視圖解析器

初始化的默認頁面路徑在classpath:/templates/ 下,視圖后綴為.html。默認路徑也可以在配置文件中修改。

管理員登陸、注銷

下面我們開始寫管理員登陸、注銷相關功能

實體類

package com.jotal.springboot08restfulcrud.entities;

public class User {

    private String username;
    private String password;
     //getter、setter、constructor、toString 
}

Dao

@Mapper
public interface UserDao {
    int login(User user);
}

映射文件

<?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE mapper
                PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.jotal.springboot08restfulcrud.dao.UserDao">

<select id="login" parameterType="user" resultType="Integer">
        select count(*) from user
        where username=#{username} and password=#{password}
</select>

</mapper>

Service

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserDao userDao;
    @Override
    public int login(User user) {
        return userDao.login(user);
    }
}

Controller

@Controller
@RequestMapping(value = "/user")
public class UserController {
    @Autowired
    UserServiceImpl userService;

    @PostMapping(value = "/login")
    public String login(@RequestParam("username") String username,
                        @RequestParam("password") String password,
                        Map<String,Object> map,
                        HttpSession session){
        
        User user = new User(username, password);
        if(userService.login(user)>0){
            //登錄成功,為了防止表單重復提交,利用重定向
            session.setAttribute("loginUser", username);
            return "redirect:/main";
        }else{
//            登陸失敗
            map.put("msg","用戶名或密碼錯誤");
            return "login";
        }

    }

    //    用戶注銷
    @GetMapping("/logout/{username}")
    public String logout(@PathVariable("username") String username,HttpSession session) {
//        清除session
        session.invalidate();
        return "redirect:/login";
    }
}

首先form表單中的請求路徑定義為該Controller方法,用POST方法提交

<form class="form-signin" th:action="@{/user/login}" method="post">

然后分別在用戶名和密碼框的輸入框加上name屬性,方便springmvc取值參數。springmvc用@RequestParam("xxx")取得前端請求發送來的參數值。

name="username"   name="password"

我們利用拿到的數據和數據庫中用戶名密碼是否一致,判斷是否成功登陸。如果登陸成功,就將用戶名添加到session中,然后重定向到主頁。

如果用戶名或者密碼不對,就利用Map添加一個包含提示信息的屬性到視圖中,然后回到login.html。

這里利用thymeleaf的 th:if 判斷決定msg是否顯示。判斷msg不為空段落才會顯示

<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>

登陸進到主頁之后,如果刷新主頁的頁面,會發現瀏覽器彈窗提示登陸表單會重復提交。這種情況利用重定向來解決!

return "redirect:/main"; 就是這一句 重定向到main,然后在我們擴展springmvc的地方加入適配main的規則。

//登錄成功之后,重定向解決表單重復提交問題
registry.addViewController("/main").setViewName("dashboard");

所以最終由thymeleaf視圖解析器最終轉發到主頁dashboard.html。

攔截器

登陸功能怎么能少得了攔截器?攔截器在登陸功能中主要是為了防止在未登錄的情況下通過uri的方式訪問需要權限的頁面。我們看一下如何在springboot中定義攔截器。

我們在component新建LoginHandlerInterceptor類實現HandlerInterceptor類。

package com.jotal.springboot08restfulcrud.component;

public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        Object user = session.getAttribute("loginUser");
        if (user == null) {
//            未登錄返回登錄頁面
            request.setAttribute("msg","未登錄,請先登錄");
            request.getRequestDispatcher("/login").forward(request,response);
            return false;
        }else{
            return true;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

我們判斷session中是否存在loginUser,loginUser是我們登陸成功才會添加到session中的。如果loginUser不存在,就在request中添加msg提示信息,然后轉發到登錄頁面。如果loginUser存在就直接放行。

我們實現了攔截器,還要加入到springmvc的環境中。在MyMvcConfig中類重寫addInterceptors方法。

//攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
            .excludePathPatterns("/login","/","/login.html","/user/login","/webjars/**","/asserts/**");
}

我們定義了攔截規則,就是除了"/login","/","login.html","/user/login"之外的所有uri都會被攔截下來進行判斷再決定是否放行。/user/login 是用來提交登陸表單請求的,"/login","/","login.html"是轉發到登錄頁的。springboot已經默認靜態資源不會被攔截器攔截。


注銷

@GetMapping("/logout/{username}")

這樣的請求會轉發到實現注銷的Controller方法。這里使用了restful api風格

我們使用@PathVariable("username")來獲取參數,然后清除session並重定向到login.html。

//    用戶注銷
    @GetMapping("/logout/{username}")
    public String logout(@PathVariable("username") String username,HttpSession session) {
//        清除session
        session.invalidate();
        return "redirect:/login";
    }

測試

輸入錯誤賬號密碼


不登錄訪問主頁http://localhost:8080/crud/main


注銷后訪問主頁http://localhost:8080/crud/main


**主頁** ![](https://img2018.cnblogs.com/blog/1738909/201908/1738909-20190813134917807-918042939.png)

今天這篇就到這里了,今天講了前端頁面和登錄注銷的功能,另外還有springboot靜態資源的映射規則,thymeleaf的視圖解析規則,以及擴展springmvc的功能。下面我們會講一些國際化的問題,以及正式開始在頁面中進行數據操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM