1. 程式人生 > 其它 >SpringBoot 員工管理系統②

SpringBoot 員工管理系統②

登入功能實現、登入攔截器

SpringBoot 員工管理系統②

1. 登入功能實現

接上回,現在才進入專案的主體部分,首先需要完成一個登入模組。

先修改前端頁面,將登入按鈕的動作修改為發起 /user/login 請求

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

然後建立 LoginController 處理這個請求,先返回一個測試資料檢視是否能成功跳轉

@Controller
public class LoginController {

    @RequestMapping("/user/login")
    @ResponseBody
    public String login(){
        return "Login!";
    }
}

確認這個請求沒有問題後,繼續修改前端,為使用者名稱和密碼輸入框提交的引數設定 name

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

然後修改控制器,接收引數並用引數處理請求

@Controller
public class LoginController {

    @RequestMapping("/user/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password,
                        Model model){
        // 簡單的登入判斷
        if(!StringUtils.isEmpty(username) && "0723".equals(password))
            // 返回檢視 dashboard.html
            return "dashboard";
        else{
            model.addAttribute("msg","使用者名稱或密碼錯誤");
            return "index";
        }
    }
}

至此登入模組基本的功能就有了,不過還沒有讓前端頁面顯示登入失敗的資訊,在前端頁面中新增

<p style="color: red" th:text="${msg}"></p>

通過 Thymeleaf 的 ${} 就能獲取到模型中設定的資訊了!

不過按照上面的方式,登入進入主頁後位址列仍是登入時發起的請求的路徑,還帶著請求的引數,不僅不好看還不安全。這就又要用到自定義 MVC 中的檢視解析器了!

首先設定表單提交的方式為 post,消除位址列中的引數!

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

然後修改控制器檢視的跳轉,由之前的直接交給檢視解析器改為重定向

        if(!StringUtils.isEmpty(username) && "0723".equals(password))
            // return "dashboard";
            return "redirect:/dashboard";
        else{
            model.addAttribute("msg","使用者名稱或密碼錯誤");
            // 首頁用 post 方式發起請求即可
            return "index";
        }

修改為重定向後,若登入成功則會重定向到 /dashboard 請求了,我們需要讓這個請求能進入註解,即在 MyMvcConfig 的配置中為這個請求設定檢視解析器

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index.html");
        registry.addViewController("/index.html").setViewName("index.html");
        // 為這個請求設定檢視解析器
        registry.addViewController("/dashboard").setViewName("dashboard.html");
    }
    ...
}

這樣登入成功進入的就是 /dashboard 請求,會被指向 dashboard.html 頁面了!

但這樣還有一個問題,即使沒有登入也能通過 /dashboard 請求進入主頁,這就需要用到登入攔截器了!

2. 登入攔截器

現在為登入模組新增一個登入攔截器,當未登入的時候不允許進入主頁!

在 com.qiyuan.config 包下建立 LoginHandlerInterceptor 攔截器,實現 HandlerInterceptor 介面

public class LoginHandlerInterceptor implements HandlerInterceptor {
    
}

實現其中的 preHandler 方法,即請求的預處理

public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 登入成功後應設定有使用者的 Session
        Object loginUser = request.getSession().getAttribute("loginUser");
        // 找不到對應的 Session,說明沒登入
        if(loginUser==null){
            request.setAttribute("msg","請先登入!");
            // 轉發後,由配置的檢視解析器跳轉
            request.getRequestDispatcher("/index.html").forward(request,response);
            // 請求不放行
            return false;
        }else {
            // 登入成功,放行
            return true;
        }
    }
}

通過獲取 Session 以判斷使用者是否登入,所以在之前登入成功的時候,應該在 Session 中寫入使用者的資訊

        if(!StringUtils.isEmpty(username) && "0723".equals(password)){
            // return "dashboard";
            // 向 Session 中寫入資訊(該方法要新增 HttpSession 引數才行)
            session.setAttribute("loginUser",username);
            return "redirect:/dashboard";
        }
        else{
            model.addAttribute("msg","使用者名稱或密碼錯誤");
            // 首頁用 post 方式發起請求即可
            return "index";
        }

最後要將攔截器註冊到 Spring 中,在 MyMvcConfig 中實現 addInterceptor 方法,和新增檢視解析器一樣

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    ...
        
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // addPathPatterns 新增需要攔截的路徑,excludePathPatterns 排除不需要攔截的路徑
        // 此處本應排除靜態資源的路徑,不過不排除也沒問題,不知道哪裡更新了
        registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").
                excludePathPatterns("/","/index.html","/user/login","/static/**");
    }
}

在新增攔截器時,通過 addPathPatterns 新增需要攔截的路徑,通過 excludePathPatterns 排除不需要攔截的路徑,非常的人性化!

至此,在未登入的情況下訪問 localhost:8080/dashboard,就會被攔截器攔截,轉發到首頁並提示請先登入了!

最後,在主頁中將顯示的名字( dashboard.html Line.46 )改為從 Session 中獲取的 loginUser

<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[session.loginUser]]</a>

這樣一個小小的登入模組也算完成了吧!