前言
這一篇我們就先引入前端頁面和相關的靜態資源,再做一下管理員的登陸和注銷的功能,為后續在頁面上操作數據做一個基礎。
前端頁面
前端的頁面是我從網上找的一個基於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:
-
- 將靜態資源版本化,更利於升級和維護。
-
- 剝離靜態資源,提高編譯速度和打包效率。
-
- 實現資源共享,有利於統一前端開發。
怎么使用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
**主頁** 
今天這篇就到這里了,今天講了前端頁面和登錄注銷的功能,另外還有springboot靜態資源的映射規則,thymeleaf的視圖解析規則,以及擴展springmvc的功能。下面我們會講一些國際化的問題,以及正式開始在頁面中進行數據操作。