Spring Boot 的 Web 開發
web 開發是開發中至關重要的一環,web 開發的核心內容包括內嵌 servlet 容器和 spring MVC。
1.springboot 的 web 開發支援
springboot 提供了 spring-boot-starter-web 為 web 開發予以支援,spring-boot-starter-web 為我們提供了嵌入的 Tomcat 以及 Spring MVC 的依賴。而 web 相關的自動配置儲存在 spring-boot-autoconfigure.jar 和 org.springframework.boot.web 下。
2.Thymeleaf 模板引擎
儘可能的少用 JSP,因為在內嵌 Servlet 容器上 JSP 執行有點問題(內嵌 Tomcat、jetty 不支援以 jar 形式執行的 JSP,Undertow 不支援 JSP)。
springboot 提供了大量的模板引擎,包括 FreeMark、Groovy、Thymeleaf、Velocity 和 Mustache,Spring Boot 中推薦使用 Thymeleaf 作為模板引擎,因為 Thymeleaf 提供了完美的 Spring MVC 的支援。
2.1 Thymeleaf 基礎知識
Thymeleaf 是一個 Java 類庫,它是一個 xml/xhtml/html5 的模板引擎,可以作為 MVC 的 Web 應用的 VIEW 層。
Thymeleaf 還提供了額外的模組與 Spring MVC 整合,所以我們可以使用 Thymeleaf 完全的替代 JSP。
2.2 與 Spring MVC 整合
在 springmvc 中,若我們需要整合一個模板引擎的話,需要定義 ViewResolver,而 ViewResolver 需要定義一個 View ,定義字首字尾。Thymeleaf 為我們提供的相關的驅動。
以上為預設提供的配置。
下面示例一個簡單的例子:
package com.pangu.demo;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import com.pangu.demo.web.entity.Person;
@Controller
@SpringBootApplication
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
@RequestMapping("/thy")
public String thymeleaf(Model model){
Person person = new Person("etfox", 22);
List<Person> people = new ArrayList<Person>();
Person person1 = new Person("etfox1", 22);
Person person2 = new Person("etfox2", 22);
Person person3 = new Person("etfox3", 22);
people.add(person1);
people.add(person2);
people.add(person3);
model.addAttribute("singlePerson", person);
model.addAttribute("people", people);
return "index";
}
@RequestMapping(value = "/json",produces={MediaType.APPLICATION_JSON_VALUE})
public String json(Model model) {
Person single = new Person("aa",11);
model.addAttribute("single", single);
return "jsonView";
}
@Bean
public MappingJackson2JsonView jsonView() {
MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
return jsonView;
}
}
index.jsp:
<html xmlns:th="http://www.thymeleaf.org"> <head> <meta content="text/html;charset=UTF-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <link th:href="@{bootstrap/css/bootstrap.min.css}" rel="stylesheet"/> <link th:href="@{bootstrap/css/bootstrap-theme.min.css}" rel="stylesheet"/> </head> <body> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">訪問model</h3> </div> <div class="panel-body"> <span th:text="${singlePerson.name}"></span> </div> </div> <div th:if="${not #lists.isEmpty(people)}"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">列表</h3> </div> <div class="panel-body"> <ul class="list-group"> <li class="list-group-item" th:each="person:${people}"> <span th:text="${person.name}"></span> <span th:text="${person.age}"></span> <button class="btn" th:onclick="'getName(\'' + ${person.name} + '\');'">獲得名字</button> </li> </ul> </div> </div> </div> <script th:src="@{jquery.min.js}" type="text/javascript"></script><!-- 2 --> <script th:src="@{bootstrap/js/bootstrap.min.js}"></script><!-- 2 --> <script th:inline="javascript"> var single = [[${singlePerson}]]; console.log(single.name+"/"+single.age) function getName(name){ console.log(name); } </script> </body> </html>
專案結構:
run。。。。。。。。。。。。。。。。
後記:SB 在自定義攔截器之後,之前的預設配置將不再生效,也就是說你配置的預設的靜態路徑啥的,剛碰到的坑!!!!!
3.Web 相關配置
3.1:Spring Boot 提供的自動配置
通過檢視 WebMvcAutoConfiguration 及 WebMvcProperties 的原始碼,可以發現 Spring Boot 為我們提供瞭如下的自動配置。
3.1.1 自動配置的 ViewResolver
(1).ContentNegotiating ViewResolver
這是 spring MVC 提供的一個特殊的 ViewResolver,ContentNegotiatingViewResolver 不是自己處理 view,而是代理給不同的 ViewResolver 來處理不同的 View,所以它有最高的優先順序。
(2).BeanNameViewResolver
在控制器(@Controller)中的一個方法的返回值的字串(檢視名)會根據 BeanNameViewResolver 去查詢 Bean 的名稱為返回字串的 View 來渲染檢視。是不是不好理解,下面舉個栗子。
定義 BeanNameViewResolver 的 Bean:
@Bean
public BeanNameViewResolver beanNameViewResolver(){
BeanNameViewResolver resolver = new BeanNameViewResolver();
return resolver;
}
定義一個 View 的 Bean ,名稱為 jsonView:
@Bean
public MappingJackson2JsonView jsonView() {
MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
return jsonView;
}
在控制器中,返回值為字串 jsonView, 它會找 Bean 的名稱為 jsonView 的檢視來渲染:@RequestMapping(value = "/json",produces={MediaType.APPLICATION_JSON_VALUE})
public String json(Model model) {
Person single = new Person("aa",11);
model.addAttribute("single", single);
return "jsonView";
}
(3).InternalResourceViewResolver
這個是一個極為常用的 ViewResolver,主要通過設定字首字尾,以及控制器中方法來返回檢視名的字串,以的到實際的頁面,springboot 的原始碼如下:
@Bean
@ConditionalOnMissingBean(InternalResourceViewResolver.class)
public InternalResourceViewResolver defaultViewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(this.prefix);//字首
resolver.setSuffix(this.suffix);//字尾
return resolver;
}
3.1.2 自動配置的靜態資源
在自動配置類的 addResourceHandlers 方法中定義了以下靜態資源自動配置。
(1)類路徑檔案
把類路徑下的/static、/public、/resources 和 /META-INF/resources 資料夾下的靜態檔案直接對映為 /**,可以通過 http://localhost:xxxx/** 直接訪問。
(2)webjar
何謂 webjar,webjar 就是我們常用的指令碼框架封裝的 jar 包中的 jar 包
把 webjar 的 META-INF/resources/webjar/ 下的靜態檔案對映為 /webjar/**,可以通過 http://localhost:8080/webjar/** 來訪問。
3.1.3 自動配置的 Formatter 和 Converter
關於自動配置 Formatter 和 Converter,我們可以看一下 WebMvcAutoconfiguration 類中的定義:
@Override
public void addFormatters(FormatterRegistry registry) {
for (Converter<?, ?> converter : getBeansOfType(Converter.class)) {
registry.addConverter(converter);
}
for (GenericConverter converter : getBeansOfType(GenericConverter.class)) {
registry.addConverter(converter);
}
for (Formatter<?> formatter : getBeansOfType(Formatter.class)) {
registry.addFormatter(formatter);
}
}
private <T> Collection<T> getBeansOfType(Class<T> type) {
return this.beanFactory.getBeansOfType(type).values();
}
從程式碼中可以看出,只要我們定義了 Converter GenericConverter Formatter 介面類的實現 bean ,這些 bean 就會自動註冊到 spring MVC 中。3.1.4 自動配置的 HttpMessageConverters
在 WebMvcAutoConfiguration 中,我們註冊了 messageConverters,程式碼如下:
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties,
WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
@Lazy HttpMessageConverters messageConverters,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
this.resourceProperties = resourceProperties;
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConverters = messageConverters;
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider
.getIfAvailable();
}
private final HttpMessageConverters messageConverters;
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.addAll(this.messageConverters.getConverters());
}
在 springboot 中如果要新增自定義的 HttpMessageConverter , 則只需定義一個你自己的 HttpMessageConverters 的 Bean,然後在此 bean 中註冊自定義 HttpMessageConverter 即可。
3.1.5 靜態首頁的支援
把靜態 index.html 檔案放置在如下目錄。
classpath:/META-INF/resources/index.html
classpath:/resources/index.html
classpath:/static/index.html
classpath:/public/index.html
當我們訪問應用根目錄 http://localhost:xxxx/ 時,會直接對映。
4.接管 Spring Boot 的 Web 配置
如果 Spring Boot 提供的 Spring MVC 預設配置不符合你的需求,則可以通過一個配置類(註解有@Configuration 的類)加上 @EnableWebMvc 註解來實現完全自己控制的 MVC 配置。
當然通常情況下可以滿足絕大多數的需求。在既需要保留 Spring Boot 提供的便利,又需要增加自己的額外配置的時候,可以定義一個配置類繼承 WebMvcConfigurerAdapter,無需使用 @EnableWebMvc 註解:
package com.pangu.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @ClassName: WebMvcConfig
* @Description: TODO 接管 SpringBoot 的 Web 配置,並不會覆蓋 WebMvcAutoConfiguration 中的 addViewControllers
* @author etfox
* @date 2018年7月1日 下午3:06:16
*
* @Copyright: 2018 www.etfox.com Inc. All rights reserved.
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* <p>Title: addViewControllers</p>
* <p>Description:http://127.0.0.1:8080/xx </p>
* @param registry
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#addViewControllers(org.springframework.web.servlet.config.annotation.ViewControllerRegistry)
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/xx").setViewName("test");
}
}
值得注意的是,在這裡重寫 addViewControllers 方法,並不會覆蓋 WebMvcAutoConfiguration 中的 addViewControllers( 此方法中,SpringBoot 將”/“對映至 index.html),這也就意味著我們自己的配置和 springboot 的配置同時生效,這也是我們推薦的新增自己的 MVC 配置的方式。5. 註冊 servlet、filter、listener
當使用嵌入式的 servlet 容器時,我們通過將 servlet、filter 和 listener 宣告為 spring bean 而達到註冊的效果:或者註冊 ServletRegistrationBean、FilterRegistrationBean 和 ServletListenerRegistrationBean 的 Bean.
6.Tomcat 配置
servlet 容器的配置,Spring Boot 預設內嵌的 Tomcat 為 servlet 容器。
6.1 配置 Tomcat
關於 Tomcat 的所有屬性都在 org.springframework.boot.autoconfigure.web.ServerProperties 配置類中做了定義,我們只需在 application.properties 配置屬性做配置即可。通用的 servlet 容器配置都以 server 作為字首,而Tomcat 特有配置都以 server 作為字首,而 Tomcat 特有配置都以 server.tomcat 作為字首。示例:
7.Favicon 配置
將 ico 檔案配置在靜態路徑下即可,通常根目錄。
8.WebSocket
8.1 什麼是 WebSocket
WebScoket 為瀏覽器和服務端提供了雙向非同步通訊的功能,即瀏覽器可以向服務端傳送訊息,服務端也可以向瀏覽器端傳送訊息。WebSocket 需瀏覽器的支援,如 IE 10+、Chrome 13+, Firefox 6+, 這對我們現在的瀏覽器來說都不是問題。
WebScoket 是通過一個 socket 來實現雙工非同步通訊能力。但是直接使用 WebSocket( 或 SockJS:WebSocket 協議的模擬,增加了當瀏覽器不支援的時候相容支援)協議開發程式顯得特別繁瑣,我們使用它的子協議 STOMP ,它是一個更高階別的協議, STOMP 協議使用一個基於幀的格式來定義訊息,與 HTTP 的 request 和 response 類似(具有類似於 @RequestMapping 的 @MessageMapping),我們會在後面實戰內容中觀察 STOMP 的幀。
8.2 Spring Boot 提供的自動配置
Spring Boot 對內嵌的 Tomcat(7/8)、Jetty9 和 Undertow 使用 websocket 提供了支援,配置原始碼存在 autoconfigure.websocket 下。
Spring Boot 為 WebSocket 提供的 stater pom 是 spring-boot-starter-websocket。
相關文章
- Spring Boot(二):Web 綜合開發Spring BootWeb
- Spring Boot (二):Web 綜合開發Spring BootWeb
- 使用Spring Boot開發Web專案Spring BootWeb
- Spring Boot React 全棧 Web 開發原始碼Spring BootReact全棧Web原始碼
- SpringBoot詳解(三)-Spring Boot的web開發Spring BootWeb
- Spring Boot第五彈,WEB開發初瞭解~Spring BootWeb
- 基於spring boot 及mybatis的web開發環境搭建Spring BootMyBatisWeb開發環境
- 基於spring-boot&spring-data-jpa的web開發環境整合SpringbootWeb開發環境
- Gradle進階:1: 結合spring boot進行web開發GradleSpring BootWeb
- Spring Boot學習5:spring-boot web容器Spring BootWeb
- spring boot(三)web模組Spring BootWeb
- Java Web之Spring BootJavaWebSpring Boot
- spring boot + vue + element-ui全棧開發入門——spring boot後端開發Spring BootVueUI全棧後端
- 開發一個Spring Boot Starter!Spring Boot
- Spring Boot入門(四):開發Web Api介面常用註解總結Spring BootWebAPI
- Java Web現代化開發:Spring Boot + Mybatis + Redis二級快取JavaWebSpring BootMyBatisRedis快取
- Spring Boot實現Web SocketSpring BootWeb
- Spring Boot學習3:web篇(中)-Spring boot Rest學習Spring BootWebREST
- Spring Boot乾貨系列:(四)開發Web應用之Thymeleaf篇 | 掘金技術徵文Spring BootWeb
- Spring Boot系列(一):Spring Boot快速開始Spring Boot
- Spring Boot Web Error Page處理Spring BootWebError
- Java Web系列:Spring Boot 基礎JavaWebSpring Boot
- Spring Boot開發(Gradle+註解)Spring BootGradle
- 高效開發 Dubbo?用 Spring Boot 可得勁!Spring Boot
- fast-spring-boot快速開發專案ASTSpringboot
- Kotlin + Spring Boot服務端開發KotlinSpring Boot服務端
- Spring boot學習(一)開啟Spring boot之旅Spring Boot
- Spring Boot乾貨系列:(五)開發Web應用之JSP篇 | 掘金技術徵文Spring BootWebJS
- 使用Spring Boot開發的10個免費開源專案Spring Boot
- 最詳細的自定義Spring Boot Starter開發教程Spring Boot
- Spring Boot學習4:web篇(下)-Spring boot (Servlet,Jsp)學習Spring BootWebServletJS
- spring boot 建立web專案(IDEA)Spring BootWebIdea
- Spring Boot 開發微信公眾號後臺Spring Boot
- 用Spring Boot顛覆Java應用開發Spring BootJava
- 《Spring Boot從零開始學(視訊教學版)》快速入門Spring Boot應用開發Spring Boot
- java使用spring boot和web3j開發以太坊區塊鏈dappJavaSpring BootWeb區塊鏈APP
- 使用 CXF 整合 Spring 開發 Web ServiceSpringWeb
- 開啟Spring Boot 之旅Spring Boot