【SpringBoot2.x】-SpringBoot Web開發中Thymeleaf、Web、Tomcat以及Faicon
Web
開發是開發中至關重要的一部分, Web
開發的核心內容主要包括內嵌Servlet
容器和Spring MVC
。更重要的是,Spring Boot``為web
開發提供了快捷便利的方式進行開發,使用依賴jar:spring-boot-starter-web
,提供了嵌入式伺服器Tomcat
以及Spring MVC
的依賴,且自動配置web
相關配置,可檢視org.springframework.boot.autoconfigure.web
。
Web
相關的核心功能:
Thymeleaf
模板引擎Web
相關配置Tomcat
配置Favicon
配置
1.模板配置
1.1原理以及原始碼分析
Spring Boot
FreeMarker
、Groovy
、 Thymeleaf
、 Velocity和Mustache
, Spring Boot
中推薦
使用Thymeleaf
作為模板引擎, 因為Thymeleaf
提供了完美的Spring MVC
的支援。
在Spring Boot
的org.springframework.boot.autoconfigure.thymeleaf
包下實現自動配置,如下所示:
ThymeleafAutoConfiguration
原始碼:
@Configuration @EnableConfigurationProperties(ThymeleafProperties.class) @ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class }) @AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class }) public class ThymeleafAutoConfiguration { //配置TemplateResolver @Configuration @ConditionalOnMissingBean(name = "defaultTemplateResolver") static class DefaultTemplateResolverConfiguration { ... } //配置TemplateEngine @Configuration protected static class ThymeleafDefaultConfiguration { ... } //配置SpringWebFluxTemplateEngine @Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true) static class ThymeleafWebMvcConfiguration { ... } //配置thymeleafViewResolver @Configuration @ConditionalOnWebApplication(type = Type.REACTIVE) @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true) static class ThymeleafWebFluxConfiguration { ... } ... }
ThymeleafAutoConfiguration
自動載入Web
所需的TemplateResolver
、TemplateEngine
、SpringWebFluxTemplateEngine
以及thymeleafViewResolver
,並通過ThymeleafProperties
進行Thymeleaf
屬性配置。詳細細節檢視官方原始碼。
ThymeleafProperties
原始碼:
//讀取application.properties配置檔案的屬性 @ConfigurationProperties(prefix = "spring.thymeleaf") public class ThymeleafProperties { private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8; public static final String DEFAULT_PREFIX = "classpath:/templates/"; public static final String DEFAULT_SUFFIX = ".html"; /** *Web模板檔案字首路徑屬性,Spring boot預設路徑為classpath:/templates/ */ private String prefix = DEFAULT_PREFIX; /** * Web模板檔案字尾屬性,預設為html */ private String suffix = DEFAULT_SUFFIX; /** * Web模板模式屬性,預設為HTML */ private String mode = "HTML"; /** * Web模板檔案編碼屬性,預設為UTF_8 */ private Charset encoding = DEFAULT_ENCODING; .... }
可以從ThymeleafProperties
中看出,Thymeleaf
的預設設定,以及可以通過字首為spring.thymeleaf
屬性修改Thymeleaf
預設配置。
1.2 示例
1).根據預設Thymeleaf
配置,在src/main/resources/
下,建立static
資料夾存放指令碼樣式靜態檔案以及templates
資料夾存放字尾為html的頁面,如下所示:
2)index.html頁面
<!DOCTYPE html>
<!-- 匯入xmlns: th=http://www.thymeleaf.org名稱空間 -->
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首面詳細</title>
</head>
<body>
<div class="user" align="center" width="400px" height="400px">
message:<span th:text="${user.message}"/><br/>
使用者名稱:<span th:text="${user.username}"/><br/>
密碼:<span th:text="${user.password}"/>
</div>
</body>
</html>
3).controller
配置:
@Controller
public class LoginController {
@Autowired
private LoginService loginService;
/**
* 將首頁設定為登陸頁面login.html
* @return
*/
@RequestMapping("/")
public String startIndex() {
return "login";
}
/**
* 登陸驗證
* @param username
* @param password
* @param model
* @return
*/
@RequestMapping("/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model) {
UserDTO userDTO = loginService.login(username, password);
model.addAttribute("user", userDTO);
return "index";
}
}
2. web
相關配置
根據WebMvcAutoConfiguration
以及WebMvcProperties
理解Spring Boot
提供的自動配置原理。
2.1 ViewResolver
以及靜態資源
Spring boot
自動配置ViewResolver
:
ContentNegotiatingViewResolver
(最高優先順序Ordered.HIGHEST_PRECEDENCE
)BeanNameViewResolver
InternalResourceViewResolver
靜態資源:
addResourceHandlers
方法預設定義了/static
、 /public
、 /resources
和/METAINF/resources
資料夾下的靜態檔案直接對映為/**
2.2 Formatter和Converter型別轉換器
addFormatters
方法會自動載入Converter
、GenericConverter
以及Formatter
的實現類、並註冊到Spring MVC中,因此自定義型別轉換器只需繼承其三個介面即可。
自定義Formatter
:
/**
* 將格式為 ccww:ccww88轉為UserDTO
*
* @Auther: ccww
* @Date: 2019/10/4 16:25
* @Description:
*/
public class StringToUserConverter implements Converter<String, UserDTO> {
@Nullable
public UserDTO convert(String s) {
UserDTO userDTO = new UserDTO();
if (StringUtils.isEmpty(s))
return userDTO;
String[] item = s.split(":");
userDTO.setUsername(item[0]);
userDTO.setPassword(item[1]);
return userDTO;
}
}
2.3 HttpMessageConverters
(HTTP request
(請求)和response
(響應)的轉換器)
configureMessageConverters
方法自動配置HttpMessageConverters:
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
this.messageConvertersProvider.ifAvailable((customConverters) -> converters
.addAll(customConverters.getConverters()));
}
通過載入由HttpMessageConvertersAutoConfiguration
定義的HttpMessageConverters
,會自動註冊一系列HttpMessage Converter
類,比如Spring MVC
預設:
ByteArrayHttpMessageConverter
StringHttpMessageConverter
ResourceHttpMessageConverter
SourceHttpMessageConverter
AllEncompassingFormHttpMessageConverter
自定義HttpMessageConverters
,只需要在自定義的HttpMessageConverters
的Bean
註冊自定義HttpMessageConverter
即可。
如下:
註冊自定義的HttpMessageConverter
:
@Configuration
public class CustomHttpMessageConverterConfig {
@Bean
public HttpMessageConverters converter(){
HttpMessageConverter<?> userJsonHttpMessageConverter=new UserJsonHttpMessageConverter();
return new HttpMessageConverters(userJsonHttpMessageConverter);
}
}
自定義HttpMessageConverter
:
public class UserJsonHttpMessageConverter extends AbstractHttpMessageConverter<UserDTO> {
private static Charset DEFUALT_ENCODE=Charset.forName("UTF-8");
public UserJsonHttpMessageConverter(){
super(new MediaType("application", "xxx-ccww", DEFUALT_ENCODE));
}
protected boolean supports(Class aClass) {
return UserDTO.class == aClass;
}
protected UserDTO readInternal(Class aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
String message = StreamUtils.copyToString(httpInputMessage.getBody(), DEFUALT_ENCODE);
String[] messages = message.split("-");
UserDTO userDTO = new UserDTO();
userDTO.setUsername(messages[0]);
userDTO.setMessage(messages[1]);
return userDTO;
}
protected void writeInternal(UserDTO userDTO, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
String out = "ccww: " + userDTO.getUsername() + "-" + userDTO.getMessage();
httpOutputMessage.getBody().write(out.getBytes());
}
}
同理,可以將Servlet、Filter以及Listener相對於的註冊即可。
2.4 MVC相關配置
自定義的MVC配置類上加@EnableWebMvc
將廢棄到Spring boot
預設配置,完全由自己去控制MVC
配置,但通常是Springboot
預設配置+所需的額外MVC
配置,只需要配置類繼承WebMvcConfigurerAdapter
即可
2.5 Tomcat
配置
可以使用兩種方式進行Tomcat
配置屬性
- 在
application.properties
配置屬性即可,Tomcat
是以"server.tomcat
"為字首的特有配置屬性,通用的是以"server
"作為字首; - 通過實現
WebServerFactoryCustomizer
介面自定義屬性配置類即可,同理其他伺服器實現對應的介面即可。
application.properties
配置屬性:
#通用Servlet容器配置
server.port=8888
#tomcat容器配置
#配置Tomcat編碼, 預設為UTF-8
server.tomcat.uri-encoding = UTF-8
# Tomcat是否開啟壓縮, 預設為關閉off
server.tomcat.compression=off
實現WebServerFactoryCustomizer
介面自定義:
/**
* 配置tomcat屬性
* @Auther: ccww
* @Date: 2019/10/5 23:22
* @Description:
*/
@Component
public class CustomTomcatServletContainer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
public void customize(ConfigurableServletWebServerFactory configurableServletWebServerFactory) {
((TomcatServletWebServerFactory)configurableServletWebServerFactory).addConnectorCustomizers(new TomcatConnectorCustomizer() {
public void customize(Connector connector) {
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
protocol.setMaxConnections(200);
protocol.setMaxThreads(200);
protocol.setSelectorTimeout(3000);
protocol.setSessionTimeout(3000);
protocol.setConnectionTimeout(3000);
protocol.setPort(8888);
}
});
}
}
替換spring boot
預設Servle
t容器tomcat
,直接在依賴中排除,並匯入相應的Servlet
容器依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starterweb</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-startertomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starterjetty</artifactId>
</dependency
2.6 自定義Favicon
自定義Favicon
只需要則只需將自己的favicon.ico
( 檔名不能變動) 檔案放置在類路徑根目錄、 類路徑META-INF/resources/
下、 類路徑resources/
下、 類路徑static/
下或類路徑