0014SpringBoot結合thymeleaf實現登錄功能


該登錄功能需要實現的需求如下:

1、輸入用戶名密碼,如果驗證通過,進入首頁,並顯示登錄的用戶名

2、如果驗證不通過,則重新進入登錄頁面,並顯示“用戶名密碼錯誤”

3、如果未經登錄,不能直接訪問首頁等靜態資源,也不能直接調用Controller層的方法,都需要轉發到登錄頁面,並提示“沒有權限,請先登錄”

具體實現如下:

 

1、定義登錄頁面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Signin Template for Bootstrap</title>
<!-- @{}的形式是鏈接資源文件或者訪問某個請求路徑 -->
<link href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">
<link href="asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet">
</head>

<body class="text-center">
<!--此處要寫成method="POST",不能寫成th:method="POST"-->
<form class="form-signin" action="dashboard.html" th:action="@{/user/login}" method="POST">
<img class="mb-4" src="asserts/img/bootstrap-solid.svg" alt="" width="72" height="72">
<!--#{}的形式是從國際化配置文件中取值-->
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<span style="color:red" th:text="${msg}" ></span>
<label class="sr-only" th:text="#{login.username}">Username</label>
<!--要寫上name="username",否則訪問LoginController方法時,沒有傳username會報錯-->
<input type="text" name="username" class="form-control" placeholder="Username" th:placeholder="#{login.username}" required="" autofocus="">
<label class="sr-only" th:text="#{login.password}">Password</label>
<input type="password" name="password" class="form-control" placeholder="Password" th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> [[#{login.remember}]]
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
<!--要寫成th:href="@{/index(l='zh_CN')}",而不能寫成th:href="@{/login.html(l='zh_CN')}",
因為直接定位到靜態資源的話是不會走自己定義的區域解析器的,
另外thymeleaf模板引擎是用中括號中放key=value的形式傳參數-->
<a class="btn btn-sm" th:href="@{/index(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index(l='en_US')}">English</a>
</form>

</body>

</html>

2、定義Controller處理登錄請求

package com.myself.controller;

import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.Map;

@Controller
public class LoginConcroller {

// @RequestMapping
// @GetMapping
// @DeleteMapping
// @RequestMapping
@PostMapping(value = "/user/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password, Map<String,Object> map, HttpSession session){
if(!StringUtils.isEmpty(username) && "123456".equals(password)){
//登錄成功,session中加入登錄用戶名,用於在成功的首頁中展示
session.setAttribute("loginUser",username);
//此處用重定向,會被我們定義的視圖解析器解析,尋找對應dashboard.html
return "redirect:/main.html";
}else{
//登錄失敗,設置失敗信息並返回登錄頁面
map.put("msg","用戶名密碼錯誤");
//由於此處不是重定向,所以相當於根據字符串直接去templates下找login.html
//所以不能寫成返回"/"或者"/index.html",否則會報找不到頁面
return "login";
}
}

}

3、定義登錄成功后進入的首頁

展示登錄用戶名
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>

4、定義攔截器用於在調用一些功能前先判斷用戶是否登錄,如果未登錄,則轉發到登錄頁面

package com.myself.component;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object obj = request.getSession().getAttribute("loginUser");
if(obj == null){
//沒有登錄,設置錯誤信息並轉發到登錄頁面
request.setAttribute("msg","沒有權限請先登陸");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else{
//已登錄,放行
return true;
}
}
}

5、在定義的配置類中以@Bean的形式加入WebMvcConfigurerAdapter組件,其中需要實現這個組件的

addInterceptors(InterceptorRegistry registry) 方法,在這里指定我們定義的攔截器攔截哪些請求,不攔截哪些請求
package com.myself.config;

import com.myself.component.LoginHandlerInterceptor;
import com.myself.component.MyLocaleResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
// @Override
// public void addViewControllers(ViewControllerRegistry registry) {
// registry.addViewController("/index").setViewName("login");
// }
//
// //注冊攔截器
// @Override
// public void addInterceptors(InterceptorRegistry registry) {
//
// registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
// .excludePathPatterns("/index.html","/","/user/login","/webjars/**","/**/*.css", "/**/*.js");
// }

//使用WebMvcConfigurerAdapter來擴展SpringMVC的功能
//所有的WebMvcConfigurerAdapter都會生效
//注意要寫在標有@Configuration的類中,要在方法上標上@Bean注解
@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
WebMvcConfigurerAdapter webMvcConfigurerAdapter = new WebMvcConfigurerAdapter(){
//視圖空值器,用於定義訪問哪些路徑時定位到哪些視圖
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//訪問http://localhost:8080/ 和 http://localhost:8080/index.html都會尋找靜態資源下的templates/login.html
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
//訪問"/main.html"會尋找靜態資源下的templates/login.html
registry.addViewController("/main.html").setViewName("dashboard");
}
//注冊攔截器,用於攔截用戶需要先登錄才能訪問資源
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/webjars/**","/**/*.css", "/**/*.js");
}
};
return webMvcConfigurerAdapter;
}

//定義區域解析器,解析國際化中英文切換
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}

}

測試:
1、訪問Controller中的方法會被轉發到登錄頁面

 

 

2、訪問css靜態資源文件可以訪問

 

 3、未登錄直接訪問首頁,會被轉發到登錄頁面

 

4、用戶名密碼輸入錯誤,會被轉發到登錄頁面,並提示錯誤信息 

 

 5、用戶名密碼輸入正確,進入首頁,變顯示登錄用戶名

 

 

 若有理解不到之處,望指教!

 

 

 

 

 

 

 

 


免責聲明!

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



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