原文位址: http://www.work100.net/training/monolithic-frameworks-spring-mvc-iot-admin3.html 更多教程: 光束雲 - 免費課程
項目重構(iot-admin3)
序号 | 文内章節 | 視訊 |
---|---|---|
1 | 概述 | - |
2 | 配置和結構重構 | |
3 | Controller控制器重構 | |
4 | 使用攔截器 | |
5 | 執行個體源碼 |
請參照如上
章節導航
進行閱讀
1.概述
我們繼續以上一章節
Spring Web中的案例項目
iot-admin2
為基礎,複制一份重命名為
iot-admin3
,修改
pom.xml
中
<artifactId>iot-admin3</artifactId>
。
接下來我們使用
Spring MVC
重構
iot-admin3
項目。
2.配置和結構重構
2.1.修改POM
将
spring-web
的依賴改為對
spring-webmvc
的依賴,同時删除對
spring-context
的依賴:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
中已經依賴了
spring-webmvc
和
spring-web
spring-context
完整的
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-admin3</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>5.2.3.RELEASE</spring.version>
<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
<javax.jstl.version>1.2</javax.jstl.version>
<junit.version>4.12</junit.version>
<slf4j.version>1.7.25</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${javax.jstl.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
</project>
2.2.配置 web.xml
CharacterEncodingFilter
配置字元集過濾器,用于解決中文編碼問題
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
DispatcherServlet
配置 Spring 的
Servlet
分發器處理所有 HTTP 的
請求
響應
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring-mvc*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
load-on-startup
标記容器是否在啟動的時候就加載這個servlet,當值為0或者大于0時,表示容器在應用啟動時就加載這個servlet;當是一個負數時或者沒有指定時,則訓示容器在該servlet被選擇時才加載;當為正數時,其值越小,啟動該servlet的優先級越高。
完整
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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-context*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring-mvc*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.3.配置 spring-mvc.xml
在目錄
src/main/resources
下建立檔案
spring-mvc.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<description>Spring MVC Configuration</description>
<!-- 加載配置屬性檔案 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:iot-admin.properties"/>
<!-- 使用 Annotation 自動注冊 Bean,隻掃描 @Controller -->
<context:component-scan base-package="net.work100.training.stage2.iot.admin" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 預設的注解映射的支援 -->
<mvc:annotation-driven />
<!-- 定義視圖檔案解析 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="${web.view.prefix}"/>
<property name="suffix" value="${web.view.suffix}"/>
</bean>
<!-- 靜态資源映射 -->
<mvc:resources mapping="/static/**" location="/static/" cache-period="31536000"/>
</beans>
相關配置說明:
-
:動态加載屬性配置檔案以變量的方式引用需要的值context:property-placeholder
-
:目前配置檔案為context:component-scan
相關,故隻需要掃描包含MVC
的注解即可,由于@Controller
配置檔案中也配置了包掃描,是以還需要排除spring-context.xml
的注解掃描。@Controller
-
:視圖檔案解析器的一種,用于配置視圖資源的路徑和需要解釋的視圖資源檔案類型,這裡有兩個需要配置的屬性InternalResourceViewResolver
(字首)以及prefix
(字尾)。suffix
-
:配置視圖資源路徑,如:prefix
/WEB-INF/views/
-
:配置視圖資源類型,如:suffix
.jsp
-
-
:靜态資源映射,主要用于配置靜态資源檔案存放路徑,如:mvc:resources
、JS
CSS
等Image
2.4.配置及結構完善
配置 iot-admin.properties
在
spring-mvc.xml
中,我們配置了
<context:property-placeholder ignore-unresolvable="true" location="classpath:iot-admin.properties"/>
用于動态加載屬性配置檔案,實際開發中我們會将系統所需的一些配置資訊封裝到
.properties
配置檔案中便于統一的管理。
src/main/resources
下建立一個名為
iot-admin.properties
的配置檔案,内容如下:
#============================#
#==== Framework settings ====#
#============================#
# views path
web.view.prefix=/WEB-INF/views/
web.view.suffix=.jsp
重構項目結構
WEB-INF
下建立目錄
views
,然後将
.jsp
檔案移動到
views
下。
webapp
static
assets
檔案夾及其所屬檔案移動到
static
目錄結構如下圖:

2.5.修改 spring-context.xml
由于
spring-mvc.xml
中已經配置了
@Controller
注解的掃描,而
spring-context.xml
中配置的是掃描全部注解,故在這裡需要将
@Controller
注解的掃描配置排除。
修改
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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<!-- 使用 Annotation 自動注冊 Bean,在主容器中不掃描 @Controller 注解,在 SpringMVC 中隻掃描 @Controller 注解。-->
<context:component-scan base-package="net.work100.training.stage2.iot.admin">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
3.Controller控制器重構
3.1.修改注解方式
UserDaoImpl 類
UserDaoImpl
類的注解方式,代碼如下:
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;
import org.springframework.stereotype.Repository;
/**
* <p>Title: UserDaoImpl</p>
* <p>Description: </p>
* <p>Url: http://www.work100.net/training/monolithic-frameworks-spring-mvc.html</p>
*
* @author liuxiaojun
* @date 2020-02-13 13:23
* ------------------- History -------------------
* <date> <author> <desc>
* 2020-02-13 liuxiaojun 初始建立
* -----------------------------------------------
*/
@Repository
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;
}
}
UserServiceImpl 類
UserServiceImpl
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.entity.User;
import net.work100.training.stage2.iot.admin.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <p>Title: UserServiceImpl</p>
* <p>Description: </p>
* <p>Url: http://www.work100.net/training/monolithic-frameworks-spring-mvc.html</p>
*
* @author liuxiaojun
* @date 2020-02-13 13:26
* ------------------- History -------------------
* <date> <author> <desc>
* 2020-02-13 liuxiaojun 初始建立
* -----------------------------------------------
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public User login(String loginId, String loginPwd) {
return userDao.getUser(loginId, loginPwd);
}
}
注解說明
- @Repository :不需要指定名稱,因為隻有一個實作類
- @Service : 不需要指定名稱,因為隻有一個實作類
- @Autowired :自動注入,Spring 自動尋找實作類來執行個體化對象
3.2.重構 Controller 代碼
修改 LoginController
LoginController
類,代碼如下:
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* <p>Title: LoginController</p>
* <p>Description: </p>
* <p>Url: http://www.work100.net/training/monolithic-frameworks-spring-mvc.html</p>
*
* @author liuxiaojun
* @date 2020-02-13 13:28
* ------------------- History -------------------
* <date> <author> <desc>
* 2020-02-13 liuxiaojun 初始建立
* -----------------------------------------------
*/
@Controller
public class LoginController {
@Autowired
private UserService userService;
/**
* 登入頁面
*
* @return
*/
@RequestMapping(value = {"", "login"}, method = RequestMethod.GET)
public String login() {
return "login";
}
/**
* 登入邏輯
*
* @param loginId 登入ID
* @param loginPwd 登入密碼
* @return
*/
@RequestMapping(value = "login", method = RequestMethod.POST)
public String login(@RequestParam(required = true) String loginId, @RequestParam(required = true) String loginPwd) {
User user = userService.login(loginId, loginPwd);
// 登入成功
if (user != null) {
return "redirect:main";
}
// 登入失敗
else {
return login();
}
}
}
建立 MainController
建立
MainController
package net.work100.training.stage2.iot.admin.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* <p>Title: MainController</p>
* <p>Description: </p>
*
* @author liuxiaojun
* @date 2020-02-20 15:19
* ------------------- History -------------------
* <date> <author> <desc>
* 2020-02-20 liuxiaojun 初始建立
* -----------------------------------------------
*/
@Controller
public class MainController {
/**
* 首頁
*
* @return
*/
@RequestMapping(value = "main", method = RequestMethod.GET)
public String main() {
return "main";
}
}
運作
重新啟動
Tomcat
驗證效果。
- @Controller
Spring MVC
中,控制器
Controller
負責處理由
DispatcherServlet
分發的請求,它把使用者請求的資料經過業務處理層處理之後封裝成一個
Model
,然後再把該
Model
傳回給對應的
View
進行展示。
Spring MVC
中提供了一個非常簡便的定義
Controller
的方法,你無需繼承特定的類或實作特定的接口,隻需使用
@Controller
标記一個類是
Controller
,然後使用
@RequestMapping
@RequestParam
等一些注解用以定義
URL 請求
Controller 方法
之間的映射,這樣的 Controller 就能被外界通路到。
此外
Controller
不會直接依賴于
HttpServletRequest
HttpServletResponse
HttpServlet
對象,它們可以通過
Controller
的方法參數靈活的擷取到。
@Controller
用于标記在一個類上,使用它标記的類就是一個
Spring MVC Controller
對象。
分發處理器将會掃描使用了該注解的類的方法,并檢測該方法是否使用了
@RequestMapping
注解。
@Controller
隻是定義了一個控制器類,而使用
@RequestMapping
注解的方法才是真正處理請求的處理器。
- @RequestMapping
RequestMapping
是一個用來處理請求位址映射的注解,可用于類或方法上。用于類上,表示類中的所有響應請求的方法都是以該位址作為父路徑。
RequestMapping
注解有六個屬性:
-
,value
method
-
:指定請求的實際位址,指定的位址可以是 URI Template 模式value
-
:指定請求的method類型,method
GET
POST
PUT
DELETE
-
-
consumes
produces
-
:指定處理請求的送出内容類型(consumes
),例如Content-Type
,application/json
text/html
-
: 指定傳回的内容類型,僅當 request 請求頭中的(produces
)類型中包含該指定類型才傳回Accept
-
-
params
headers
-
:指定 request 中必須包含某些參數值是,才讓該方法處理params
-
:指定 request 中必須包含某些指定的headers
值,才能讓該方法處理請求header
-
4.使用攔截器
4.1.簡介
Spring Web MVC 的處理器攔截器,類似于 Servlet 開發中的過濾器 Filter,用于對處理器進行預處理和後處理。
4.2.應用場景
- 日志記錄:記錄請求資訊的日志,以便進行資訊監控、資訊統計、計算 PV(Page View)等
- 權限檢查:如登入檢測,進入處理器檢測檢測是否登入,如果沒有直接傳回到登入頁面
- 性能監控:有時候系統在某段時間莫名其妙的慢,可以通過攔截器在進入處理器之前記錄開始時間,在處理完後記錄結束時間,進而得到該請求的處理時間
- 通用行為:讀取 Cookie 得到使用者資訊并将使用者對象放入請求,進而友善後續流程使用,還有如提取 Locale、Theme 資訊等,隻要是多個處理器都需要的即可使用攔截器實作
4.3.如何使用攔截器
- Spring MVC 攔截器需要實作
接口,該接口定義了HandlerInterceptor
個方法,分别為:3
-
preHandle()
-
postHandle()
-
afterCompletion()
-
通過重寫這 3 個方法來對使用者的請求進行攔截處理的。
-
:preHandle(HttpServletRequest request, HttpServletResponse response, Object handle)
該方法在請求處理之前進行調用。Spring MVC 中的 Interceptor 是鍊式調用的,在一個應用中或者說是在一個請求中可以同時存在多個 Interceptor 。
每個 Interceptor 的調用會依據它的聲明順序依次執行,而且最先執行的都是 Interceptor 中的
preHandle
方法,是以可以在這個方法中進行一些前置初始化操作或者是對目前請求做一個預處理,也可以在這個方法中進行一些判斷來決定請求是否要繼續進行下去。
該方法的傳回值是布爾值
Boolean
類型的,當它傳回為
false
時,表示請求結束,後續的 Interceptor 和 Controller 都不會再執行;當傳回值為
true
時,就會繼續調用下一個 Interceptor 的
preHandle
方法,如果已經是最後一個 Interceptor 的時候,就會是調用目前請求的 Controller 中的方法。
-
postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)
通過
preHandle
方法的解釋咱們知道這個方法包括後面要說到的
afterCompletion
方法都隻能在目前所屬的 Interceptor 的
preHandle
方法的傳回值為
true
的時候,才能被調用。
postHandle
方法在目前請求進行處理之後,也就是在 Controller 中的方法調用之後執行,但是它會在 DispatcherServlet 進行視圖傳回渲染之前被調用,是以咱們可以在這個方法中對 Controller 處理之後的 ModelAndView 對象進行操作。
postHandle
方法被調用的方向跟
preHandle
是相反的,也就是說,先聲明的 Interceptor 的
postHandle
方法反而會後執行。
-
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)
也是需要目前對應的 Interceptor 的 preHandle 方法的傳回值為
true
時才會執行。
是以,該方法将在整個請求結束之後,也就是在 DispatcherServlet 渲染了對應的視圖之後執行,這個方法的主要作用是用于進行資源清理的工作。
4.4.建立登入攔截器
我們知道對系統的相關操作是需要登入後才可以使用的,當未登入時是無法直接通路需要登入權限的操作的,為了做到這個效果,我們使用登入攔截器來判斷使用者是否登入,如果使用者已登入則放行讓使用者繼續操作,否則就将其跳轉到登入頁。
net.work100.training.stage2.iot.admin.web
包下建立一個包
interceptor
,然後在
interceptor
包下定義一個名為
LoginInterceptor
的攔截器,代碼如下:
package net.work100.training.stage2.iot.admin.web.interceptor;
import net.work100.training.stage2.iot.admin.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* <p>Title: LoginInterceptor</p>
* <p>Description: </p>
* <p>Url: http://www.work100.net/training/monolithic-frameworks-spring-mvc.html</p>
*
* @author liuxiaojun
* @date 2020-02-20 16:22
* ------------------- History -------------------
* <date> <author> <desc>
* 2020-02-20 liuxiaojun 初始建立
* -----------------------------------------------
*/
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("LoginInterceptor");
User user = (User) request.getSession().getAttribute("user");
// 未登入
if (user == null) {
response.sendRedirect("/login");
}
// 為 true 時放行,進入 postHandle
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
LoginInterceptor
攔截器的主要功能是檢測使用者是否登入,如果未登入則跳轉至登入頁(/login)
4.5.在 spring-mvc.xml 中配置攔截器
攔截器定義後還需要在
spring-mvc.xml
中配置攔截器,代碼如下:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/static/**"/>
<bean class="net.work100.training.stage2.iot.admin.web.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
-
:定義一個攔截器mvc:interceptor
-
:映射路徑,需要攔截的請求路徑mvc:mapping
-
:需要排除的請求路徑,比如登入頁本身是不需要攔截的,這裡還包括了靜态資源路徑也是不需要攔截的mvc:exclude-mapping
-
:配置指定的攔截器對象bean class
-
4.6.完善使用場景
我們實際的使用場景中還應該有個判斷邏輯:當使用者已經登入了,通路
/login
時,需要将請求跳轉至
/main
建立攔截器 PermissionInterceptor
這時我們需要再建立一個攔截器
PermissionInterceptor
package net.work100.training.stage2.iot.admin.web.interceptor;
import net.work100.training.stage2.iot.admin.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* <p>Title: PermissionInterceptor</p>
* <p>Description: </p>
* <p>Url: http://www.work100.net/training/monolithic-frameworks-spring-mvc.html</p>
*
* @author liuxiaojun
* @date 2020-02-20 21:16
* ------------------- History -------------------
* <date> <author> <desc>
* 2020-02-20 liuxiaojun 初始建立
* -----------------------------------------------
*/
public class PermissionInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("PermissionInterceptor");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if ("login".equals(modelAndView.getViewName())) {
User user = (User) request.getSession().getAttribute("user");
if (user != null) {
response.sendRedirect("/main");
}
}
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
修改 spring-mvc.xml 配置
增加
PermissionInterceptor
攔截器的配置,代碼如下:
<!-- 攔截器配置(攔截器的執行順序為:從下往上) -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/static/**"/>
<bean class="net.work100.training.stage2.iot.admin.web.interceptor.LoginInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="net.work100.training.stage2.iot.admin.web.interceptor.PermissionInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
攔截器的執行順序為:從下往上,即先定義的後執行
spring-mvc.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<description>Spring MVC Configuration</description>
<!-- 加載配置屬性檔案 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:iot-admin.properties"/>
<!-- 使用 Annotation 自動注冊 Bean,隻掃描 @Controller -->
<context:component-scan base-package="net.work100.training.stage2.iot.admin" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 預設的注解映射的支援 -->
<mvc:annotation-driven/>
<!-- 定義視圖檔案解析 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="${web.view.prefix}"/>
<property name="suffix" value="${web.view.suffix}"/>
</bean>
<!-- 靜态資源映射 -->
<mvc:resources mapping="/static/**" location="/static/" cache-period="31536000"/>
<!-- 攔截器配置(攔截器的執行順序為:從下往上) -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/static/**"/>
<bean class="net.work100.training.stage2.iot.admin.web.interceptor.LoginInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="net.work100.training.stage2.iot.admin.web.interceptor.PermissionInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
4.7.運作驗證
重新開機
Tomcat
,分别驗證
LoginInterceptor
PermissionInterceptor
攔截器是否生效。
5.執行個體源碼
執行個體源碼已經托管到如下位址:
- https://github.com/work100-net/training-stage2/tree/master/iot-admin3 https://github.com/work100-net/training-stage2/tree/master/iot-admin3
- https://gitee.com/work100-net/training-stage2/tree/master/iot-admin3 https://gitee.com/work100-net/training-stage2/tree/master/iot-admin3
上一篇:
簡介下一篇:
Maven 子產品化開發如果對課程内容感興趣,可以掃碼關注我們的或
公衆号
,及時關注我們的課程更新
QQ群