Spring Boot真正的核心功能是自動配置和快速整合,通常Spring Boot應用的前端MVC框架依然使用Spring MVC。Spring Boot提供的spring-boot-starter-web啟動器嵌入了Spring MVC的依賴,并為Spring MVC提供了大量自動配置,可以適用于大多數Web開發場景。 除了使用自動配置所提供的功能,開發者也可以通過自定義配置類定制Spring MVC的配置。
Spring Boot為Spring MVC自動配置提供的特性
在Spring Boot項目中,一旦引入了Web依賴啟動器spring-boot-starter-web,那么Spring Boot整合Spring MVC框架默認實現的一些XxxAutoConfiguration自動配置類就會自動生效,幾乎可以在無任何額外配置的情況下進行Web開發。
Spring Boot為Spring MVC提供了自動配置,并在Spring MVC默認功能的基礎上添加了以下特性。
(1)引入了視圖解析器 ContentNegotiatingViewResolver和BeanNameViewResolver。
(2)為包括WebJars在內的靜態資源提供支持。
(3)自動注冊 Converter、GenericConverter和Formatter。
(4)支持使用HttpMessageConverters消息轉換器。
(5)自動注冊 MessageCodesResolver。
(6)支持靜態項目首頁index.html。
(7)支持定制應用圖標favicon.ico。
(8)自動初始化Web數據綁定器ConfigurableWebBindingInitializer。
自定義Spring MVC配置
在Spring Boot應用中使用Spring MVC時,如果希望在為Spring MVC自動配置提供相關特性的同時,再增加一些自定義的Spring MVC配置,例如添加攔截器、視圖控制器等,可以通過自定義WebMvcConfigurer類型的配置類來實現。
1.配置靜態資源映射
通常Web應用中會需要使用靜態資源,例如,JavaScript文件、CSS文件和HTML文件等。單獨使用Spring MVC時,導入靜態資源文件后,需要配置靜態資源的映射,否則無法正常訪問。Spring Boot中提供了默認的靜態資源映射,當訪問項目中任意的靜態資源時,Spring Boot會默認從以下路徑中從上往下進行查找:
(1)classpath:/META-INF/resources/
(2)classpath:/resources/
(3)classpath:/static/
(4)classpath:/public/
這個查找順序可以通過源碼查看:WebMvcAutoConfiguration--》搜索getStaticLocations--》進入該方法--》尋著軌跡就能找到。
修改靜態資源存放位置:
spring.resources.static-locations=字符串數組
例如:
在chapter03項目中的 src/main/resources/static和 src/main/resources目錄下分別創建main.html文件和index.html文件,并在項目啟動后分別在瀏覽器中對這兩個靜態資源進行訪問。
如果想訪問非默認靜態資源文件夾下的資源,可以通過配置類和配置文件2種方式實現自定義靜態資源的映射。
(1)通過配置類實現靜態資源映射
配置類需要實現WebMvcConfigurer接口,在重寫該接口的addResourceHandlers()方法中指定資源訪問路徑和資源之間的映射關系。
(2)通過配置文件實現靜態資源映射
Spring Boot在Spring MVC的自動配置中提供了對應的屬性可以配置靜態資源訪問路徑和資源的映射。
下面以通過配置類實現靜態資源映射為例,演示配置靜態資源映射。
(1)創建靜態資源。
在src/main/resources目錄下,創建文件夾backend,并在文件夾中創建HTML文件index.html和login.htm。
(2)配置靜態資源映射。
在config子包下創建配置類WebMvcConfig,該配置類實現WebMvcConfigurer接口,并重寫該接口的方法實現自定義Spring MVC的配置,具體如文件3-11所示。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.
ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.
WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");}}
?(3)測試程序效果。啟動項目,在瀏覽器中訪問backend文件夾下的index.html。
2.配置視圖控制器
使用Spring MVC默認的配置進行開發時,如果僅實現無業務邏輯的頁面跳轉,也需要創建Controller類,然后定義方法跳轉到頁面,操作比較麻煩。對此,可以在視圖控制器中添加自定義的映射,直接將請求映射為視圖。
下面通過案例演示在視圖控制器中配置請求和視圖的映射,具體如下。
(1)配置視圖控制器映射信息。在文件3-11中重寫WebMvcConfigurer接口的addViewControllers()方法,在該方法中添加訪問路徑和視圖的映射。
@Override
public void addViewControllers(ViewControllerRegistry registry) {/*如果在thymeleaf中會出錯,因為配置了前綴和后綴,*視圖名"/backend/login.html"加上前綴后綴后,這個地址肯定不存在,*直接寫邏輯視圖名即可*/ //registry.addViewController("/backend/toLoginPage").setViewName("/backend/login.html");//registry.addViewController("/backend").setViewName("/backend/index.html");//在thymeleaf環境下訪問模板頁面registry.addViewController("/backend/toLoginPage2").setViewName("login");registry.addViewController("/backend").setViewName("index");
}
(2)測試程序效果。啟動項目,在瀏覽器中訪問http://localhost:8080/backend/toLoginPage2。
總結:只適合較為簡單的無參數get請求跳轉,對于有參數或者需要業務處理的跳轉需求,最好采用傳統方式。
3.配置攔截器
攔截器可以根據請求的URL對請求進行攔截,主要應用于登錄校驗、權限驗證、亂碼解決、性能監控和異常處理等方面。在Spring Boot項目中配置攔截器也非常簡單,只需要定義攔截器和注冊攔截器即可。?
攔截過程
下面通過案例演示在Spring Boot項目中配置攔截器。
(1)定義攔截器。創建interceptor子包,在該包下創建攔截器類,該類實現了 HandlerInterceptor接口,并重寫了接口的preHandle()方法,具體如文件3-12所示。
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 獲取請求路徑String requestURI = request.getRequestURI();// 獲取登錄用戶Object loginUser = request.getSession().getAttribute("loginUser");// 如果請求路徑是"/backend"開頭的,并且用戶沒有登錄,//那么將請求重定向到登錄頁面或者內部轉發if (requestURI.startsWith("/backend") && loginUser == null) {response.sendRedirect("/toLoginPage");//request.getRequestDispatcher("/toLoginPage").forward(request,response);return false;}return true;}}
(2)注冊攔截器。
在文件3-11中重寫WebMvcConfigurer接口的addInterceptors()方法,在該方法中添加攔截器。
@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/toLoginPage");}
(3)效果測試
重啟項目,啟動成功后,在瀏覽器上訪問http://localhost:8080/backend
動手試一試
不攔截靜態資源,比如圖片,css 。