springBoot與Web開發
圖片上傳真的很累,想看圖的可以訪問我的個人博客:
http://www.bestrivenlf.cn/note/getNoteList
1、SpringBoot對靜態資源的映射規則
1.1、對公共資源的映射規則
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
可以看出靜態資源的一種映射規則是:registry.hasMappingForPattern("/webjars/**"),即"/webjars/**"
,代碼中指出:所有的/webjars/**,都去classpath:/META-INF/resources/webjars/找資源
那麼webjars是什麼?
webjars是以jar包的方式引入靜態資源;可以通過maven導入的方式導入像jquery啊bootstrap等這些靜態框架資源,具體可以參考webjars的官方文檔:https://www.webjars.org/
在pom.xml中加入如下聲明:
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1-1</version>
</dependency>
查看導入的jar包發現如下圖:
jquery的資源就被成功引入到項目中去了。
比如我發一個請求:localhost:8080/webjars/abc,SpringBoot會去classpath:/META-INF/resources/webjars/abc尋找資源。
1.2、對個人資源的映射規則
公共的框架可以通過webjars引入,那麼自己的一些CSS或者圖片如何引入呢?我們可以通過SpringBoot的代碼來看一下是如何定義的:
public WebMvcProperties() {
this.localeResolver = WebMvcProperties.LocaleResolver.ACCEPT_HEADER;
this.dispatchTraceRequest = false;
this.dispatchOptionsRequest = true;
this.ignoreDefaultModelOnRedirect = true;
this.throwExceptionIfNoHandlerFound = false;
this.logResolvedException = false;
this.staticPathPattern = "/**";
發現另的一種staticPathPattern默認是"/**"
任何路徑訪問當前項目的任何資源都是去以下幾個地方尋找:
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{
"classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/"
};
加上/**一共五種路徑:
- “classpath:/META-INF/resources/”
- “classpath:/resource”
- “classpath:/static/”
- “classpath:/public/”
- “/**”
這些目錄有些是有的,有些則需要自己創建,如下:
那麼假設我們要訪問某一個資源的時候可以通過localhost:8080/abc 去以上五個資源文件夾裏面找abc
1.3、歡迎頁的映射規則
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
return new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
}
//getWelcomePage()得到歡迎頁
//getStaticPathPattern()得到映射規則
深入getWelcomePage()發現:
private Optional<Resource> getWelcomePage() {
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
從locations裏獲取"index.html"作爲歡迎頁,getStaticLocations()的結果也就是上面提到的那四種默認的靜態資源文件夾。
也就是說,當我們訪問localhost:8080/時,應當跳轉歡迎頁,歡迎頁則去靜態資源默認的文件夾下尋找index.html作爲歡迎頁。
1.4、圖標映射規則
這裏就不貼代碼了,按照上述分析方法,發現,所有的圖標資源"**/favicon.ico"也是在靜態資源文件夾下尋找。
1.5、修改靜態資源文件夾的路徑
/**
由於staticLocations定義在ResourceProperties配置類中,
發現 prefix = "spring.resources",
想要修改staticLocation,則可以通過配置文件配置spring.resources.static-location的值即可
**/
@ConfigurationProperties(
prefix = "spring.resources",
ignoreUnknownFields = false
)
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
private String[] staticLocations;
private boolean addMappings;
private final ResourceProperties.Chain chain;
private final ResourceProperties.Cache cache;
public ResourceProperties() {
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
this.addMappings = true;
this.chain = new ResourceProperties.Chain();
this.cache = new ResourceProperties.Cache();
}
可以作如下配置:
spring.resources.static-locations=classpath:/hello/,classpath:/liufan/
#由於這個量是個數組,所以可以配置多個路徑,用逗號隔開即可。
2、模板引擎
2.1、什麼是模板引擎
springBoot默認是不支持jsp的,如果不使用jsp,只使用html,會非常不方便,所以SpringBoot建議使用模板引擎。實JSP也是一種模板引擎,只不過由於各種原因,springboot默認不支持了。
那麼什麼叫模板引擎?其
下面來先看一張圖:
所謂模板引擎,參考上述圖片解釋就是,首先定義一個Template,其中有一些變量是動態的,需要後臺傳入,訪問的時候通過後臺得到數據後,通過模板引擎將動態數據和模板結合組裝成output,即我們看到的頁面,這就是模板引擎實現的功能。
springBoot官方推薦的模板引擎是:thymeleaf.
2.2、thymeleaf
2.2.1、引入thymeleaf
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.2.2、thymeleaf使用示例
首先我們來看一下springBoot對於thymeleaf的自動配置:
@ConfigurationProperties(
prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING;
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
private boolean checkTemplate = true;
private boolean checkTemplateLocation = true;
private String prefix = "classpath:/templates/";
private String suffix = ".html";
private String mode = "HTML";
只要我們把HTML頁面放在DEFAULT_PREFIX = "classpath:/templates/"下即可訪問相應的頁面。
例如,我在templates文件夾下創建一個test.html頁面,現在我們來寫一個例子:
/**
* 原來SpringMVC會將返回的success進行前後綴封裝後定位到相應的頁面
* 現在SpringBoot也一樣,加上前綴classpath:/templates/,後綴.html
* 會定位到classpath:/templates/test.html頁面
* @return
*/
@RequestMapping("/test")
public String test(){
return "test";
}
這個頁面就是thymeleaf來自動渲染的。
2.2.3、引入thymeleaf的命名空間
<html xmlns:th="http://www.thymeleaf.org">
這樣可以擁有thymeleaf的自動提示功能
thymeleaf的語法詳情可以查看thymeleaf的官方文檔
2.2.4、常用語法
<p th:text="#{home.welcome}">Welcome to our grocery store!</p>
#{}:從配置文件中獲取數據
${} :從域中獲取數據
<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>
解析html標籤,不會對其進行轉義
- 其他:
1、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).
2、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>
3、Message Expressions: #{...}:獲取國際化內容
4、Link URL Expressions: @{...}:定義URL;
@{/order/process(execId=${execId},execType='FAST')}
5、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: _