1. 程式人生 > 實用技巧 >spring-boot-learning-Web開發知識

spring-boot-learning-Web開發知識

1)、建立SpringBoot應用,選中我們需要的模組;

2)、SpringBoot已經預設將這些場景配置好了,只需要在配置檔案中指定少量配置就可以執行起來

3)、自己編寫業務程式碼;

檔名的功能

xxxxAutoConfiguration:幫我們給容器中自動配置元件;
xxxxProperties:配置類來封裝配置檔案的內容;

SpringBoot對靜態資源的對映規則;

可配置:

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware {
  //可以設定和靜態資源有關的引數,快取時間等

自動配置類裡面所規定的一些對映:

WebMvcAuotConfiguration:
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
                return;
            }
            Integer cachePeriod = this.resourceProperties.getCachePeriod();
            if (!registry.hasMappingForPattern("/webjars/**")) {
                customizeResourceHandlerRegistration(
                        registry.addResourceHandler("/webjars/**")
                                .addResourceLocations(
                                        "classpath:/META-INF/resources/webjars/")
                        .setCachePeriod(cachePeriod));
            }
            String staticPathPattern = this.mvcProperties.getStaticPathPattern();
              //靜態資原始檔夾對映
            if (!registry.hasMappingForPattern(staticPathPattern)) {
                customizeResourceHandlerRegistration(
                        registry.addResourceHandler(staticPathPattern)
                                .addResourceLocations(
                                        this.resourceProperties.getStaticLocations())
                        .setCachePeriod(cachePeriod));
            }
        }

        //配置歡迎頁對映
        @Bean
        public WelcomePageHandlerMapping welcomePageHandlerMapping(
                ResourceProperties resourceProperties) {
            return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
                    this.mvcProperties.getStaticPathPattern());
        }

       //配置喜歡的圖示
        @Configuration
        @ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
        public static class FaviconConfiguration {

            private final ResourceProperties resourceProperties;

            public FaviconConfiguration(ResourceProperties resourceProperties) {
                this.resourceProperties = resourceProperties;
            }

            @Bean
            public SimpleUrlHandlerMapping faviconHandlerMapping() {
                SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
                mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
                  //所有  **/favicon.ico 
                mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
                        faviconRequestHandler()));
                return mapping;
            }

            @Bean
            public ResourceHttpRequestHandler faviconRequestHandler() {
                ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
                requestHandler
                        .setLocations(this.resourceProperties.getFaviconLocations());
                return requestHandler;
            }

        }

所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找資源;==

webjars:以jar包的方式引入靜態資源;

http://www.webjars.org/

、"/**" 訪問當前專案的任何資源,都去(靜態資源的資料夾)找對映==

"classpath:/META-INF/resources/", 
"classpath:/resources/",
"classpath:/static/", 
"classpath:/public/" 
"/":當前專案的根路徑

localhost:8080/abc === 去靜態資原始檔夾裡面找abc

歡迎頁; 靜態資原始檔夾下的所有index.html頁面;被"/**"對映;==

localhost:8080/ 找index頁面

所有的 **/favicon.ico 都是在靜態資原始檔下找;==

這個favicon.ico,就是我們訪問網站的小標誌

模板引擎

將資料庫的內容和靜態檔案的變數都由模板引擎去解決對應的變數問題
最後模板引擎呈現給大家的最終的畫面

SpringBoot推薦的Thymeleaf;

語法更簡單,功能更強大;

引入thymeleaf 依賴:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

因為我們沒有設定版本,所以預設spring-boot裡面的版本是2.多

如果我們要切換預設的版本的化:

<properties>
        <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
        <!-- 佈局功能的支援程式  thymeleaf3主程式  layout2以上版本 -->
        <!-- thymeleaf2   layout1-->
        <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
  </properties>

spring-boot 2.0之前是使用2.1.1版本的,但是我檢視後發現2.0以後使用了高本吧:

檢視步驟:pom.xml檔案--spring-boot-starter-parent

--spring-boot-dependencies

---搜尋thymeleaf就行

所以使用spring-boot不需要切換版本

thymeleaf 的使用方法和語法:

@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

    private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");

    private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");

    public static final String DEFAULT_PREFIX = "classpath:/templates/";

    public static final String DEFAULT_SUFFIX = ".html";
      //

只要我們把HTML頁面放在classpath:/templates/,thymeleaf就能自動渲染;

在html檔案裡面導圖名稱空間,支援提示寫入

<html lang="en" xmlns:th="http://www.thymeleaf.org">

簡單使用:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>成功!</h1>
    <!--th:text 將div裡面的文字內容設定為 -->
    <div th:text="${hello}">這是顯示歡迎資訊</div>
</body>
</html>

thymeleaf的語法規則:

1)、th:text;改變當前元素裡面的文字內容;

th:任意html屬性;來替換原生屬性的值

2)、表示式

Simple expressions:(表示式語法)
    Variable Expressions: ${...}:獲取變數值;OGNL;
            1)、獲取物件的屬性、呼叫方法
            2)、使用內建的基本物件:
                #ctx : the context object.
                #vars: the context variables.
                #locale : the context locale.
                #request : (only in Web Contexts) the HttpServletRequest object.
                #response : (only in Web Contexts) the HttpServletResponse object.
                #session : (only in Web Contexts) the HttpSession object.
                #servletContext : (only in Web Contexts) the ServletContext object.
                
                ${session.foo}
            3)、內建的一些工具物件:
#execInfo : information about the template being processed.
#messages : methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.
#uris : methods for escaping parts of URLs/URIs
#conversions : methods for executing the configured conversion service (if any).
#dates : methods for java.util.Date objects: formatting, component extraction, etc.
#calendars : analogous to #dates , but for java.util.Calendar objects.
#numbers : methods for formatting numeric objects.
#strings : methods for String objects: contains, startsWith, prepending/appending, etc.
#objects : methods for objects in general.
#bools : methods for boolean evaluation.
#arrays : methods for arrays.
#lists : methods for lists.
#sets : methods for sets.
#maps : methods for maps.
#aggregates : methods for creating aggregates on arrays or collections.
#ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).

    Selection Variable Expressions: *{...}:選擇表示式:和${}在功能上是一樣;
        補充:配合 th:object="${session.user}:
   <div th:object="${session.user}">
    <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
    <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
    <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
    </div>
    
    Message Expressions: #{...}:獲取國際化內容
    Link URL Expressions: @{...}:定義URL;
            @{/order/process(execId=${execId},execType='FAST')}
    Fragment Expressions: ~{...}:片段引用表示式
            <div th:insert="~{commons :: main}">...</div>
            
Literals(字面量)
      Text literals: 'one text' , 'Another one!' ,…
      Number literals: 0 , 34 , 3.0 , 12.3 ,…
      Boolean literals: true , false
      Null literal: null
      Literal tokens: one , sometext , main ,…
Text operations:(文字操作)
    String concatenation: +
    Literal substitutions: |The name is ${name}|
Arithmetic operations:(數學運算)
    Binary operators: + , - , * , / , %
    Minus sign (unary operator): -
Boolean operations:(布林運算)
    Binary operators: and , or
    Boolean negation (unary operator): ! , not
Comparisons and equality:(比較運算)
    Comparators: > , < , >= , <= ( gt , lt , ge , le )
    Equality operators: == , != ( eq , ne )
Conditional operators:條件運算(三元運算子)
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    Default: (value) ?: (defaultvalue)
Special tokens:
    No-Operation: _ 

簡單的例子:

controller:

@Controller
public class HelloController {
//    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "hello";
    }

    @RequestMapping("/success")
    public String success(Map<String,Object> map){
        map.put("hello","<h1>傻逼</h1>");
        map.put("users", Arrays.asList("AAA","bbbb","VVVV"));

        return  "success";
    }

}

html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>流弊</h1>
    <div th:text="${hello}"></div>
    <hr/>
    <div th:text="${hello}"></div>

    <div th:utext="${hello}"></div>
    <hr/>

    <h4 th:text="${user}" th:each="user:${users}"></h4>
    <hr/>

    <h4>
        <span th:each="user:${users}">[[${user}]]</span>
    </h4>

</body>
</html>

結果:

SpringMVC自動配置原理:

springboot自動配置好了SpringMVC

下面是springboot預設配mVC:

111111Inclusion of `ContentNegotiatingViewResolver` and `BeanNameViewResolver` beans.
  自動配置了ViewResolver(檢視解析器:根據方法的返回值得到檢視物件(View),檢視物件決定如何
  渲染(轉發?重定向?))
  
  ContentNegotiatingViewResolver:組合所有的檢視解析器;他是通過載入所有的解析器的
    所以我們定製的時候,只需要編寫檢視解析器並載入到容器當中就行了,

注意:其他的也類似

- Support for serving static resources, including support for WebJars (see below
  .靜態資原始檔夾路徑,webjars
- Static `index.html` support. 靜態首頁訪問 - Custom `Favicon` support (see below). favicon.ico

自動註冊了 of `Converter`, `GenericConverter`, `Formatter` beans.
- Converter:轉換器;  public String hello(User user):型別轉換使用Converter
- `Formatter`  格式化器;  2017.12.17===Date;

Support for `HttpMessageConverters` (see below).

- HttpMessageConverter:SpringMVC用來轉換Http請求和響應的;User---Json;

- `HttpMessageConverters` 是從容器中確定;獲取所有的HttpMessageConverter;

  ==自己給容器中新增HttpMessageConverter,只需要將自己的元件註冊容器中(@Bean,@Component)==

Automatic registration of `MessageCodesResolver` (see below).定義錯誤程式碼生成規則

Automatic use of a `ConfigurableWebBindingInitializer` bean (see below).

==我們可以配置一個ConfigurableWebBindingInitializer來替換預設的;(新增到容器)==
初始化WebDataBinder;
請求資料=====JavaBean;

這裡有所有場景的自動配置類:org.springframework.boot.autoconfigure.web

如何修改Springboot預設配置:

模式:

1111Springboot在自動配置很多元件的時候,先看容器中有沒有使用者自己配置的(@Bean,@Component),
如果有就用使用者配置的,如果沒有,才自動配置。 如果有些元件可以有多個(例如ViewResolver)將使用者配置的和自己買咯人的組合起來
2222在SpringBoot中會有非常多的xxxConfigurer幫助我們進行擴充套件配置
3333在SpringBoot中會有很多的xxxCustomizer幫助我們進行定製配置

 

如果僅僅靠springboot的預設配置是不能滿足的

例如:

我們之前配置springMVC的配置檔案:

<?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: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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <mvc:view-controller path="/hello" view-name="success"/>
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean></bean>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

編寫一個配置類(@Configuration),是一個WebMvcConfigurerAdapter型別的類,且不能標註@EnableWebMvc

public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/hello").setViewName("success");
    }
}

原理:

1111WebMvcAutoConfiguration是springMVC的自動配置類

222會匯入@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})

EnableWebMvcConfiguration這個類:
    @Configuration(
        proxyBeanMethods = false
    )
    public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {

繼承的類中:

    @Autowired(
        required = false
    )
    public void setConfigurers(List<WebMvcConfigurer> configurers) {
        if (!CollectionUtils.isEmpty(configurers)) {
            this.configurers.addWebMvcConfigurers(configurers);
        }

    }

從容器中獲取所有的webmvcConfigurer。

333容器中所有的WebMvcConfigurer都會一起起作用

444我們的配置類也會被呼叫

  效果:springmvc自動配置和我們的擴充套件配置都會起作用

全面接管SpringMVC:

springboot對springMVC的自動配置不需要了,所有都是我們自己配置,所有的web場景自動配置都失效了

原理:

  111核心內容

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}

222載入的類

@Configuration(
    proxyBeanMethods = false
)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

333回頭看看自動配置類

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {

帶顏色部分,只有容器中沒有這個元件的時候,自動配置類才生效

444因為@EnableWebMvc將DelegatingWebMvcConfigurationextends WebMvcConfigurationSupport匯入進來了

555匯入進來的WebMvcConfigurationSupport只是springMVC最基本的功能