【SpringBoot2.x】-SpringBoot Web開發中Thymeleaf、Web、Tomcat以及Favicon

clipboard.png

github:https://github.com/Ccww-lx/Sp...
模塊:spring-boot-starter-base-webhtml

  Web開發是開發中相當重要的一部分, Web開發的核心內容主要包括內嵌Servlet容器和Spring MVC。更重要的是,Spring Boot`爲web開發提供了快捷便利的方式進行開發,使用依賴jar:spring-boot-starter-web,提供了嵌入式服務器Tomcat以及Spring MVC的依賴,且自動配置web相關配置,可查看org.springframework.boot.autoconfigure.web`。git

Web相關的核心功能:github

  • Thymeleaf模板引擎
  • Web相關配置
  • Tomcat配置
  • Favicon配置

1.模板配置

1.1原理以及源碼分析

  Spring Boot提供了大量模板引擎, 包含括FreeMarkerGroovyThymeleafVelocity和MustacheSpring Boot中推薦
使用Thymeleaf做爲模板引擎, 由於Thymeleaf提供了完美的Spring MVC的支持。 web

  在Spring Bootorg.springframework.boot.autoconfigure.thymeleaf包下實現自動配置,以下所示:spring

ThymeleafAutoConfiguration源碼:tomcat

@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所需的TemplateResolverTemplateEngineSpringWebFluxTemplateEngine以及thymeleafViewResolver,並經過ThymeleafProperties進行Thymeleaf屬性配置。詳細細節查看官方源碼。服務器

ThymeleafProperties源碼:app

//讀取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默認配置。ide

1.2 示例

1).根據默認Thymeleaf配置,在src/main/resources/下,建立static文件夾存放腳本樣式靜態文件以及templates文件夾存放後綴爲html的頁面,以下所示:spring-boot

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 方法會自動加載ConverterGenericConverter以及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,只須要在自定義的HttpMessageConvertersBean註冊自定義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配置屬性

  1. application.properties配置屬性便可,Tomcat是以"server.tomcat"爲前綴的特有配置屬性,通用的是以"server"做爲前綴;
  2. 經過實現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 默認Servlet容器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/下或類路徑public/下。



最後可關注公衆號:【ccww筆記】 一塊兒學習,天天會分享乾貨,還有學習視頻領取!

clipboard.png

相關文章
相關標籤/搜索