SpringBoot導(dǎo)學(xué)課課件 第4章 Spring Boot的Web開(kāi)發(fā)_第1頁(yè)
SpringBoot導(dǎo)學(xué)課課件 第4章 Spring Boot的Web開(kāi)發(fā)_第2頁(yè)
SpringBoot導(dǎo)學(xué)課課件 第4章 Spring Boot的Web開(kāi)發(fā)_第3頁(yè)
SpringBoot導(dǎo)學(xué)課課件 第4章 Spring Boot的Web開(kāi)發(fā)_第4頁(yè)
SpringBoot導(dǎo)學(xué)課課件 第4章 Spring Boot的Web開(kāi)發(fā)_第5頁(yè)
已閱讀5頁(yè),還剩54頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第4章SpringBoot的Web開(kāi)發(fā)第4章SpringBoot的Web開(kāi)發(fā)4.1SpringBoot對(duì)Web開(kāi)發(fā)的支持4.2

自定義消息轉(zhuǎn)換器HttpMessageConverter4.3SpringBoot序列化和反序列化JSON數(shù)據(jù)4.4SpringBoot對(duì)靜態(tài)資源的訪問(wèn)4.5Thymeleaf模板引擎4.6

錯(cuò)誤處理4.7CORS支持4.8

文件上傳和下載4.9

嵌入式Servlet容器支持4.10

對(duì)JSP的支持

4.24.1SpringBoot對(duì)Web開(kāi)發(fā)的支持SpringBoot對(duì)Web功能的支持,從開(kāi)發(fā)、測(cè)試、部署、運(yùn)維(安全)等都提供了相應(yīng)的starter支持。SpringBoot使用spring-boot-starter-web為Web開(kāi)發(fā)提供支持,spring-boot-starter-web又依賴于spring-web和spring-webmvc,其中spring-webmvc就代表了SpringMVC框架。

使用Spring進(jìn)行Web開(kāi)發(fā)時(shí),只需要在項(xiàng)目中引入對(duì)應(yīng)Web開(kāi)發(fā)框架的依賴啟動(dòng)器即可,一旦引入了Web依賴啟動(dòng)器spring-boot-starter-web,那么SpringBoot整合SpringMVC框架默認(rèn)實(shí)現(xiàn)的一些自動(dòng)配置類就會(huì)自動(dòng)生效,幾乎可在無(wú)任何額外配置的情況下進(jìn)行Web開(kāi)發(fā)。34.1SpringBoot對(duì)Web開(kāi)發(fā)的支持SpringBoot為SpringMVC提供的auto-configuration適用于大多數(shù)應(yīng)用,并在Spring默認(rèn)功能上添加了以下特性:(1)內(nèi)置了兩個(gè)視圖解析器:ContentNegotiatingViewResolver和BeanNameViewResolver。(2)對(duì)服務(wù)器靜態(tài)資源提供支持,包括對(duì)WebJars的支持。(3)自動(dòng)注冊(cè)了Converter、GenericConverter轉(zhuǎn)換器和Formatter格式化器。(4)支持使用HttpMessageConverters來(lái)注冊(cè)HttpMessageConverter。(5)自動(dòng)注冊(cè)消息代碼解析器MessageCodeResolver。(6)支持靜態(tài)的index.html首頁(yè)。(7)支持定制應(yīng)用圖標(biāo)favicon.ico。(8)自動(dòng)初始化Web數(shù)據(jù)綁定器ConfigurableWebBindingInitializer。大多數(shù)時(shí)候使用默認(rèn)配置即可滿足開(kāi)發(fā)需求。44.2自定義消息轉(zhuǎn)換器HttpMessageConverterSpringMVC使用HttpMessageConverter接口來(lái)轉(zhuǎn)換HTTP請(qǐng)求和響應(yīng)。例如,可以將對(duì)象自動(dòng)轉(zhuǎn)換為JSON(通過(guò)使用Jackson庫(kù))或XML(通過(guò)使用JacksonXML擴(kuò)展,或者通過(guò)使用JAXB,如果JacksonXML擴(kuò)展不可用)。1.常見(jiàn)JSON技術(shù)

在JSON的使用中,幾種常見(jiàn)的JSON技術(shù),介紹如下:(1)Jackson(2)Gson(3)FastJson54.2自定義消息轉(zhuǎn)換器HttpMessageConverter2.默認(rèn)實(shí)現(xiàn)返回JSON數(shù)據(jù)SpringMVC中使用消息轉(zhuǎn)換器HttpMessageConverter對(duì)JSON轉(zhuǎn)換提供了很好的支持,在SpringBoot中更進(jìn)一步,對(duì)相關(guān)配置做了進(jìn)一步的簡(jiǎn)化。下面我們通過(guò)默認(rèn)實(shí)現(xiàn)返回JSON數(shù)據(jù)來(lái)講解。(1)使用SpringInitializr方式創(chuàng)建一個(gè)名為chapter04的SpringBoot項(xiàng)目,在Dependencies依賴下選擇Web節(jié)點(diǎn)下的SpringWeb,在pom.xml中的Web依賴代碼如下:

該依賴中默認(rèn)加入了jackson-databind作為JSON處理器。6<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

……<dependencies>4.2自定義消息轉(zhuǎn)換器HttpMessageConverter(2)在chapter04項(xiàng)目的com.yzpc包下新建一個(gè)entity包,并在該包下新建Person的實(shí)體類,代碼如下:7packagecom.yzpc.entity;importcom.fasterxml.jackson.annotation.JsonFormat;importjava.util.Date;publicclassPerson{privateStringname;privateStringsex;privateintage;@JsonFormat(pattern="yyyy-MM-dd")privateDatevisitDate;//省略getter、setter方法}4.2自定義消息轉(zhuǎn)換器HttpMessageConverter(3)在com.yzpc包下新建一個(gè)controller包,并在該包下新建PersonController類,定義show()方法返回Person對(duì)象,代碼如下:8packagecom.yzpc.controller;importcom.yzpc.entity.Person;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;importjava.util.Date;@RestControllerpublicclassPersonController{@GetMapping("/show")publicPersonshow(){

Personperson=newPerson();

person.setName("張三");

person.setSex("男");

person.setAge(22);

person.setVisitDate(newDate());

returnperson;}}4.2自定義消息轉(zhuǎn)換器HttpMessageConverter(4)啟動(dòng)項(xiàng)目,在瀏覽器中輸入http://localhost:8080/show,即可看到返回了JSON數(shù)據(jù),如圖4-1所示。

通過(guò)Spring中默認(rèn)提供的MappingJackson2HttpMessageConverter來(lái)實(shí)現(xiàn)的,如果需要添加或自定義轉(zhuǎn)換器,可以使用SpringBoot的HttpMessageConverters,代碼如下:9importorg.springframework.boot.autoconfigure.http.HttpMessageConverters;importorg.springframework.context.annotation.*;importorg.springframework.http.converter.*;@Configuration(proxyBeanMethods=false)publicclassMyConfiguration{

@Bean

publicHttpMessageConverterscustomConverters(){HttpMessageConverter<?>additional=...HttpMessageConverter<?>another=...

returnnewHttpMessageConverters(additional,another);}}4.2自定義消息轉(zhuǎn)換器HttpMessageConverter3.使用Gson轉(zhuǎn)換器

常見(jiàn)的JSON處理器除了jackson-databind之外,還有Gson作為JSON解析庫(kù),這里使用Gson來(lái)自定義轉(zhuǎn)換器實(shí)現(xiàn)JSON輸出。(1)在chapter04項(xiàng)目下,使用Gson時(shí),需要在pom.xml中去除spring-boot-starter-web下的默認(rèn)jackson-databind依賴,然后加入Gson依賴,這里使用的Gson版本為2.8.7,依賴代碼如下:10<dependencies><dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

<exclusions>

<exclusion>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>com.google.code.gson</groupId>

<artifactId>gson</artifactId>

<version>2.8.7</version>

</dependency>

</dependencies>4.2自定義消息轉(zhuǎn)換器HttpMessageConverter(2)在com.yzpc包下新建一個(gè)converter包,并在該包下新建GsonConfig類,代碼如下:11@Configuration

publicclassGsonConfig{

@Bean

publicGsonHttpMessageConvertergsonHttpMessageConverter(){//自己提供一個(gè)GsonGsonHttpMessageConverter的實(shí)例

GsonHttpMessageConverterconverter=newGsonHttpMessageConverter();

GsonBuilderbuilder=newGsonBuilder();

//設(shè)置Gson解析時(shí)日期的格式

builder.setDateFormat("yyyy-MM-dd");

//設(shè)置Gson解析時(shí)修飾符為protected的字段被過(guò)濾

builder.excludeFieldsWithModifiers(Modifier.PROTECTED);

//創(chuàng)建Gson對(duì)象放入GsonHttpMessageConverter的實(shí)例并返回converter

Gsongson=builder.create();

converter.setGson(gson);

returnconverter;

}

}4.2自定義消息轉(zhuǎn)換器HttpMessageConverter(3)修改Person類的中的age字段的修飾符改為protected,代碼如下:

(4)重新啟動(dòng)項(xiàng)目,在瀏覽器中訪問(wèn)http://localhost:8080/show,運(yùn)行效果如圖4-2所示。12publicclassPerson{

privateStringname;

privateStringsex;

protectedintage;

privateDatevisitDate;

//省略getter、setter方法

}4.3SpringBoot序列化和反序列化JSON數(shù)據(jù)

現(xiàn)在Java開(kāi)發(fā)大都是前后端分離,通過(guò)傳遞JSON進(jìn)行信息傳遞。不可避免會(huì)遇到對(duì)象的序列化和反序列化。JSON的序列化是指將Java中的對(duì)象轉(zhuǎn)換成JSON字符串,反過(guò)來(lái),將JSON字符串轉(zhuǎn)換為Java中的對(duì)象,就是JSON的反序列化。下面通過(guò)示例來(lái)演示JSON數(shù)據(jù)的序列化和反序列化,步驟如下:(1)在chapter04項(xiàng)目中,打開(kāi)Chapter04ApplicationTests項(xiàng)目測(cè)試類,添加toJson()方法實(shí)現(xiàn)序列化,代碼如下:13@SpringBootTestclassChapter04ApplicationTests{

……@Test

publicvoidtoJson(){

Mapmap=newHashMap();

map.put("id","1001");

map.put("name","zhangsan");

Gsongson=newGson();

//將Java對(duì)象轉(zhuǎn)為json字符串,稱為"json序列化"

Stringjson=gson.toJson(map);

System.out.println(json);

}}4.3SpringBoot序列化和反序列化JSON數(shù)據(jù)(2)運(yùn)行測(cè)試方法toJson(),在控制臺(tái)輸出相應(yīng)的Json格式的字符串,如圖4-3所示。(3)在項(xiàng)目測(cè)試類中,添加fromJson()方法實(shí)現(xiàn)Json數(shù)據(jù)的反序列化,代碼如下:(4)運(yùn)行測(cè)試方法fromJson(),控制臺(tái)輸出如圖4-4所示。14@TestpublicvoidfromJson(){

Stringjson="{\"name\":\"zhangsan\",\"id\":\"1001\"}";

Gson

gson=newGson();//newTypeToken<要轉(zhuǎn)換的對(duì)象類型>(){}.getType()

Mapmap=gson.fromJson

(json,new

TypeToken<Map>(){}.getType());

System.out.println(map);}

4.4SpringBoot對(duì)靜態(tài)資源的訪問(wèn)在SpringMVC中,對(duì)于靜態(tài)資源都需要開(kāi)發(fā)者手動(dòng)配置靜態(tài)資源過(guò)濾。SpringBoot中對(duì)此也提供了自動(dòng)化配置,可以簡(jiǎn)化靜態(tài)資源過(guò)濾配置。4.4.1默認(rèn)規(guī)則默認(rèn)情況下,SpringBoot將通過(guò)類加載路徑下的/static目錄(或/public或/resources或/META-INF/resources)或當(dāng)前應(yīng)用的根路徑來(lái)提供靜態(tài)資源。

對(duì)應(yīng)大部分開(kāi)發(fā)者而言,只要將JS腳本、CSS樣式文件、圖片等靜態(tài)統(tǒng)一放在加載路徑下的/static或/public目錄中即可。154.4.1默認(rèn)規(guī)則它使用SpringMVC中的ResourceHttpRequestHandler,以便您可以通過(guò)添加自己的WebMvcConfigurer并重寫(xiě)addResourceHandlers方法來(lái)修改該行為。SpringBoot中對(duì)于SpringMVC的自動(dòng)化配置都在WebMvcAutoConfiguration類中,因此對(duì)于默認(rèn)靜態(tài)資源過(guò)濾策略可以從這個(gè)類獲悉。在該類中有一個(gè)WebMvcAutoConfigurationAdapter,實(shí)現(xiàn)WebMvcConfigurer接口,WebMvcConfigurer接口中有一個(gè)添加資源處理的方法addResourceHandlers,是用來(lái)配置靜態(tài)資源過(guò)濾的,該方法在WebMvcAutoConfigurationAdapter類中得到了實(shí)現(xiàn)。

下面來(lái)通過(guò)源碼的實(shí)現(xiàn)來(lái)查看一下。164.4.1默認(rèn)規(guī)則

SpringBoot默認(rèn)會(huì)過(guò)濾所有的靜態(tài)資源,所以/**訪問(wèn)當(dāng)前項(xiàng)目下的任何資源,都去以下五個(gè)路徑下尋找資源,也就是說(shuō)可將靜態(tài)資源放到這5個(gè)位置中的任意一個(gè)。(1) classpath:/META-INF/resources/(2) classpath:/resources/(3) classpath:/static/(4) classpath:/public/(5) /:當(dāng)前項(xiàng)目的根路徑上面靜態(tài)資源加載路徑的優(yōu)先級(jí)為:/META-INF/resources>/resources>/static>/public。一般情況下,SpringBoot項(xiàng)目不需要Webapp(WebContent)目錄,故“/”暫不考慮。174.4.1默認(rèn)規(guī)則在chapter04的項(xiàng)目中,在resources目錄下分別創(chuàng)建如上4個(gè)目錄,4個(gè)目錄中分別放入同名的靜態(tài)資源index.html,各目錄下的index.html靜態(tài)網(wǎng)頁(yè)的內(nèi)容不同,如圖4-5所示。

重新啟動(dòng)項(xiàng)目,在地址欄輸入http://localhost:8080/index.html,可看到META-INF/resources/目錄下的index.html;

如果將/META-INF/resources目錄下的index.html刪除,重啟1項(xiàng)目,就會(huì)訪問(wèn)/resources目錄下的index.html,以此類推,如圖4-5所示。

如果使用IntelliJIDEA創(chuàng)建SpringBoot項(xiàng)目,就會(huì)默認(rèn)創(chuàng)建出static目錄,靜態(tài)資源一般放在這個(gè)目錄下即可。184.4.1默認(rèn)規(guī)則在前面chapter04項(xiàng)目的PersonController類中,添加方法hello(),代碼如下:

重新啟動(dòng)該項(xiàng)目,在地址欄輸入http://localhost:8080/index.html,效果如圖4-6所示。從這個(gè)結(jié)果可以看出,靜態(tài)映射/**請(qǐng)求進(jìn)來(lái),先去找Controller看能不能處理,不能處理的所有請(qǐng)求,交給靜態(tài)資源處理器。靜態(tài)資源處理器就去找以上的幾個(gè)目錄,如果靜態(tài)資源能找到則訪問(wèn),否則就會(huì)訪問(wèn)失敗。19@GetMapping("/index.html")publicStringhello(){

return"HELLO!";

}4.4.1默認(rèn)規(guī)則如果jar文件以webjars格式打包,則從訪問(wèn)jar文件提供路徑為/webjars/**的任何資源。

SpringBoot需要使用webjars,我們可以去搜索一下,如果要使用jQuery,我們只要引入jQuery對(duì)應(yīng)版本的pom依賴即可,如圖4-7所示。打開(kāi)網(wǎng)站可以看到下面有很多前端js組件的maven引入,這里引入jquery3.6.0版本的依賴,代碼如下所示:

在chapter04項(xiàng)目中,將這段依賴添加進(jìn)pom.xml文件,在maven的jar包里面看到該jquery引入。重啟項(xiàng)目,在瀏覽器訪問(wèn)http://localhost:8080/webjars/jquery/3.6.0/jquery.js,就可訪問(wèn)jquery.js文件,如圖4-8所示。20<!--webjar引入jquery--><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.6.0</version></dependency>4.4.2自定義規(guī)則如果默認(rèn)的靜態(tài)資源訪問(wèn)規(guī)則不能滿足開(kāi)發(fā)需求,也可以自定義規(guī)則。例如,可以添加靜態(tài)資源訪問(wèn)的前綴,自定義靜態(tài)資源過(guò)濾規(guī)則有以下兩種方法。1.在配置文件中定義默認(rèn)情況下,資源映射在/**上,可以使用spring.mvc.static-path-pattern屬性對(duì)其進(jìn)行調(diào)整,在chapter04項(xiàng)目的perties文件中直接定義過(guò)濾規(guī)則和靜態(tài)資源位置,代碼如下:

重新啟動(dòng)項(xiàng)目,訪問(wèn)http://localhost:8080/hello/index.html,即看到static目錄下index.html靜態(tài)網(wǎng)頁(yè)文件,如圖4-9所示。

21spring.mvc.static-path-pattern=/hello/**spring.web.resources.static-locations=classpath:/static/4.4.2自定義規(guī)則

2.Java編碼定義除在配置文件中定義外,也可通過(guò)Java編碼方式來(lái)定義,只需要實(shí)現(xiàn)WebMvcConfigurer接口即可,然后實(shí)現(xiàn)該接口的addResourceHandlers。在chapter04項(xiàng)目的com.yzpc包下,新建一個(gè)config包,在該包中新建MyWebMvcConfig類,代碼如下所示:重新啟動(dòng)項(xiàng)目,訪問(wèn)http://localhost:8080/hello/index.html,即可看到public目錄下的index.html靜態(tài)網(wǎng)頁(yè)文件,如圖4-10所示。22@Configuration

publicclassMyWebMvcConfigimplementsWebMvcConfigurer{

@Override

publicvoidaddResourceHandlers

(ResourceHandlerRegistryregistry){

registry.addResourceHandler("/hello/**").addResourceLocations("classpath:/public/");}

}4.5Thymeleaf模板引擎4.5.1Thymeleaf簡(jiǎn)介Thymeleaf是SpringBoot推薦的模板引擎,SpringBoot為之提供了完美的支持,它是一種現(xiàn)代的基于服務(wù)器端的Java模板引擎技術(shù),也是一種優(yōu)秀的面向Java的XML、XHTML、HTML5頁(yè)面模板。Thymeleaf標(biāo)準(zhǔn)方言中的大多數(shù)處理器都是屬性處理器,這種頁(yè)面模板即使在未處理之前,瀏覽器也可以正確地顯示HTML模板文件,因?yàn)闉g覽器會(huì)簡(jiǎn)單地忽略其不認(rèn)識(shí)的屬性。

下面包含JSP腳本的HTML片段代碼,它不能在模板被解析之前通過(guò)瀏覽器直接顯示。23<inputtype="text"name="userName"value="${}"/>4.5.1Thymeleaf簡(jiǎn)介

下面是一段含有Thymeleaf語(yǔ)句的HTML代碼。

在模板被解析之前,瀏覽器不識(shí)別th:value屬性,那么該屬性就會(huì)被直接忽略,這樣瀏覽器照樣可以正確顯示這些信息,并可打開(kāi)一個(gè)默認(rèn)值(例如“用戶名”)。當(dāng)該模板被解析之后,th:value屬性指定的表達(dá)式解析得到的值又會(huì)取代原來(lái)的value屬性值,解析之后th:value屬性就消失了,該屬性對(duì)于瀏覽器就不存在了。Thymeleaf解決了前端開(kāi)發(fā)人員要和后端開(kāi)發(fā)人員配置一樣環(huán)境的尷尬和低效。它通過(guò)屬性進(jìn)行模板渲染,不需要引入不能被瀏覽器識(shí)別的新的標(biāo)簽。24<inputtype="text"name="userName"value="用戶名"th:value="${}"/>4.5.2引入Thymeleaf在SpringBoot項(xiàng)目中使用Thymeleaf模板,首先需要在項(xiàng)目中引入Thymeleaf依賴,直接在pom.xml文件中添加Thymeleaf依賴即可,依賴代碼如下:還需要在HTML文件中加入“<htmllang=”en“xmlns:th=”“>”命名空間,這樣就能完成Thymeleaf標(biāo)簽的渲染。25<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>4.5.2引入ThymeleafSpringBoot默認(rèn)的頁(yè)面映射路徑(即模板文件存放位置)為“classpath:/templates/*.html”,靜態(tài)文件路徑為“classpath:/static/”,其中可以存放CSS、JS等模板共用的靜態(tài)文件。

在全局配置文件perties文件中,可以配置Thymeleaf模板解析器屬性,一般Web項(xiàng)目都會(huì)使用下列配置,示例代碼如下所示。26spring.thymeleaf.cache=false#關(guān)閉模板緩存spring.thymeleaf.encoding=UTF-8#模板的編碼格式spring.thymeleaf.mode=HTML5#模板的模板模式spring.thymeleaf.servlet.content-type=text/html#指定文檔類型spring.thymeleaf.prefix=classpath:/templates/#指定模板頁(yè)面存放路徑spring.thymeleaf.suffix=.html#指定模板頁(yè)面的后綴名4.5.3Thymeleaf語(yǔ)法規(guī)則1.常用標(biāo)簽

在HTML頁(yè)面上使用Thymeleaf標(biāo)簽,Thymeleaf標(biāo)簽?zāi)軌騽?dòng)態(tài)地替換掉靜態(tài)內(nèi)容,動(dòng)態(tài)顯示頁(yè)面內(nèi)容。為了讓大家更直觀地認(rèn)識(shí)Thymeleaf,下面我們展示一個(gè)在HTML文件中嵌入Thymeleaf的頁(yè)面文件,示例代碼如下。27<!DOCTYPEhtml><htmllang="en"

xmlns:th=""><head>

<metacharset="UTF-8">

<linkrel="stylesheet"type="text/css"media="all"

href="../../css/gtvg.css“th:href="@{/css/gtvg.css}"/>

<title>Title</title>

</head>

<body>

<pth:text="${hello}">您好,歡迎進(jìn)入Thymeleaf</p>

</body>

</html>4.5.3Thymeleaf語(yǔ)法規(guī)則

Thymeleaf模板提供了很多th:標(biāo)簽,具體如表4-1所示。28th:標(biāo)簽使用說(shuō)明th:id用于id的聲明,類似于HTML中的id屬性th:insert頁(yè)面片段包含(類似JSP中include標(biāo)簽)th:replace頁(yè)面片段包含(類似JSP中include標(biāo)簽)th:each元素遍歷(類似JSP中的c:forEach標(biāo)簽)th:if條件判斷,條件成立時(shí)顯示th標(biāo)簽的內(nèi)容th:unless條件判斷,條件不成立時(shí)顯示th標(biāo)簽的內(nèi)容th:switch條件判斷,進(jìn)行選擇性匹配th:case多路選擇配合th:switch使用th:object用于替換對(duì)象th:with用于定義局部變量th:標(biāo)簽使用說(shuō)明th:attr通用屬性修改th:attrprepend通用屬性修改,將計(jì)算結(jié)果追加前綴到現(xiàn)有屬性值th:attrappend通用屬性修改,將計(jì)算結(jié)果追加后綴到現(xiàn)有屬性值th:value屬性值修改,指定標(biāo)簽屬性值th:href用于設(shè)定鏈接地址th:src用于圖片類地址引入th:text用于指定標(biāo)簽顯示的文本內(nèi)容th:utext用于指定標(biāo)簽顯示的文本內(nèi)容,對(duì)特殊標(biāo)簽不轉(zhuǎn)義th:fragment聲明片段th:remove移除片段4.5.3Thymeleaf語(yǔ)法規(guī)則Thymeleaf模板頁(yè)面雖然與純HTML頁(yè)面基本相似,但已經(jīng)不是一個(gè)標(biāo)準(zhǔn)的HTML5頁(yè)面了,這是因?yàn)樵赥hymeleaf頁(yè)面中使用的th:*屬性是HTML5規(guī)范所不允許的。如果我們想要使用Thymeleaf模板進(jìn)行純HTML5的頁(yè)面開(kāi)發(fā),可以使用data-th-*屬性替換th:*屬性進(jìn)行頁(yè)面開(kāi)發(fā)。例如將上面的示例使用data-th-*屬性進(jìn)行修改,示例代碼如下。使用data-th-*屬性這種方式,不會(huì)出現(xiàn)屬性的快捷提示,對(duì)于開(kāi)發(fā)者來(lái)說(shuō)不太方便,因此在實(shí)際開(kāi)發(fā)中,相對(duì)推薦使用引入Thymeleaf標(biāo)簽的形式進(jìn)行模板引擎頁(yè)面的開(kāi)發(fā)。29<!DOCTYPEhtml><htmllang="en"><head>

<metacharset="UTF-8">

<linkrel="stylesheet"type="text/css"media="all"

href="../../css/gtvg.css“data-th-href="@{/css/gtvg.css}"/>

<title>Title</title>

</head>1

<body>

<pdata-th-text="${hello}">您好,歡迎進(jìn)入Thymeleaf</p>

</body>

</html>4.5.3Thymeleaf語(yǔ)法規(guī)則2.標(biāo)準(zhǔn)表達(dá)式Thymeleaf模板引擎提供了多種標(biāo)準(zhǔn)表達(dá)式語(yǔ)法,如表4-2所示。

Thymeleaf還提供了其他更多的語(yǔ)法支持,例如文本表達(dá)式、算式表達(dá)式、布爾表達(dá)式、比較表達(dá)式等,可查看具體的官方文檔說(shuō)明,下面對(duì)常用的表達(dá)式進(jìn)行講解。30表達(dá)式語(yǔ)法說(shuō)明${…}變量表達(dá)式*{…}選擇變量表達(dá)式#{…}消息表達(dá)式@{…}鏈接URL表達(dá)式~{…}片段表達(dá)式4.5.3Thymeleaf語(yǔ)法規(guī)則(1)變量表達(dá)式變量表達(dá)式${…}主要用于獲取上下文中的變量值,示例代碼如下:

使用了Thymeleaf模板的變量表達(dá)式${…}用來(lái)動(dòng)態(tài)獲取p標(biāo)簽中的內(nèi)容。Thymeleaf為變量所在域提供了一些內(nèi)置對(duì)象,如下:

如果要在Thymeleaf模板引擎頁(yè)面中動(dòng)態(tài)獲取當(dāng)前國(guó)家信息,可以使用#locale內(nèi)置對(duì)象,示例代碼如下:31<pth:text="${title}">標(biāo)題</p>#ctx:上下文對(duì)象。#vars:上下文變量。#locale:上下文區(qū)域設(shè)置。#request:(僅在Web上下文中)HttpServletRequest對(duì)象。#response:(僅在Web上下文中)HttpServletResponse對(duì)象。#session:(僅在Web上下文中)HttpSession對(duì)象。#servletContext:(僅在Web上下文中)ServletContext對(duì)象。Thelocalecountryis:

<spanth:text="${#locale.country}">US</span>.4.5.3Thymeleaf語(yǔ)法規(guī)則(2)選擇變量表達(dá)式

選擇變量表達(dá)式*{…}和變量表達(dá)式${…}用法類似,*{…}一般用于從被選定對(duì)象而不是上下文中獲取屬性值,如果沒(méi)有選定對(duì)象,則和變量表達(dá)式一樣,示例代碼如下:32

<divth:object="${session.user}">

<p>Name:<spanth:text="${#object.firstName}">Zhang</span>.</p>

<p>Surname:<spanth:text="${session.user.lastName}">Sanfeng</span>.</p>

<p>Nationality:<spanth:text="*{nationality}">China</span>.</p>

</div>4.5.3Thymeleaf語(yǔ)法規(guī)則(3)消息表達(dá)式消息表達(dá)式#{…}主要用于Thymeleaf模板頁(yè)面國(guó)際化內(nèi)容的動(dòng)態(tài)替換和展示,使用消息表達(dá)式#{…}進(jìn)行國(guó)際化設(shè)置時(shí),還需要提供一些國(guó)際化配置文件。(4)鏈接表達(dá)式鏈接表達(dá)式@{…}一般用于頁(yè)面跳轉(zhuǎn)或資源的引入,在Web開(kāi)發(fā)中占據(jù)著非常重要的地位,示例代碼如下:(5)片段表達(dá)式片段表達(dá)式~{…}是一種用來(lái)將標(biāo)記片段移動(dòng)到模板中的方法。其中,最常見(jiàn)的用法是使用th:insert或th:replace屬性插入片段,示例代碼如下:33<ahref="details.html"

th:href="@{http://localhost:8080/order/details(orderId=${o.id})}">view</a><ahref="details.html"

th:href=“@{/order/details(orderId=${o.id})}">view</a><divth:insert="~{thymeleafDemo::title}"></div>4.5.4整合Thymeleaf下面通過(guò)示例講解SpringBoot整合Thymeleaf模板引擎。(1)創(chuàng)建SpringBoot項(xiàng)目,引入Thymeleaf依賴(2)編寫(xiě)配置文件(3)創(chuàng)建實(shí)體類(4)創(chuàng)建控制器類(5)創(chuàng)建模板頁(yè)面(6)效果測(cè)試

直接用瀏覽器打開(kāi)index.html頁(yè)面,就是前端所能看到的靜態(tài)效果,如圖所示。啟動(dòng)項(xiàng)目,在瀏覽器訪問(wèn)http://localhost:8080/book/showBooks,進(jìn)入圖書(shū)信息列表的頁(yè)面,運(yùn)行效果如圖所示。344.6錯(cuò)誤處理4.6.1異常處理機(jī)制SpringBoot的錯(cuò)誤處理其實(shí)就是對(duì)SpringMVC異常處理的自動(dòng)配置。因此SpringBoot同樣可支持兩種錯(cuò)誤處理:以SpringBoot提供的自動(dòng)配置為基礎(chǔ),通過(guò)提供一些配置信息來(lái)改變SpringBoot默認(rèn)的錯(cuò)誤處理行為。使用@ResponseStatus、@ExceptionHandler、@ControllerAdvice等基于AOP的異常處理機(jī)制,這是直接基于SpringMVC異常處理機(jī)制進(jìn)行錯(cuò)誤處理。SpringBoot默認(rèn)提供了一個(gè)/error映射來(lái)處理所有的錯(cuò)誤,對(duì)于普通瀏覽器,它會(huì)生成一個(gè)“whitelabel”錯(cuò)誤頁(yè)面,如請(qǐng)求http://localhost:8080/hello時(shí)發(fā)生狀態(tài)值為404的錯(cuò)誤,會(huì)有默認(rèn)的頁(yè)面展示給用戶,如圖4-14所示。354.6.1異常處理機(jī)制雖然SpringBoot為我們提供了默認(rèn)的錯(cuò)誤頁(yè)面映射,但是在實(shí)際應(yīng)用中,錯(cuò)誤頁(yè)面對(duì)用戶來(lái)說(shuō)并不友好,要對(duì)其進(jìn)行自定義,添加view解析為error。要完全替代默認(rèn)行為,可以實(shí)現(xiàn)ErrorController并注冊(cè)該類型的Bean定義,或提供自定義的ErrorAttributes實(shí)現(xiàn)類,通過(guò)該類中的getErrorAttributes()方法即可向錯(cuò)誤屬性中添加哪些異常信息。SpringBoot為ErrorAttributes提供的實(shí)現(xiàn)類為DefaultErrorAttributes,它生成的錯(cuò)誤屬性包含如下異常信息。36timestamp:錯(cuò)誤發(fā)生時(shí)間。status:HTTP狀態(tài)碼。error:錯(cuò)誤原因。message:異常消息。path:錯(cuò)誤發(fā)生時(shí)請(qǐng)求的URL路徑。exception:異常的類名。errors:BindingResult異常里的各種錯(cuò)誤(如果這個(gè)錯(cuò)誤是由異常引起的)。trace:異常跟蹤信息(如果這個(gè)錯(cuò)誤是由異常引起的)。4.6.2自定義錯(cuò)誤頁(yè)SpringBoot可指定自定義的錯(cuò)誤頁(yè)面來(lái)代替原有的默認(rèn)錯(cuò)誤頁(yè)面,只要將錯(cuò)誤頁(yè)面放在/error目錄下即可。自定義的錯(cuò)誤頁(yè)面既可是靜態(tài)的HTML頁(yè)面,也可是動(dòng)態(tài)的頁(yè)面模板,應(yīng)該將靜態(tài)的HTML錯(cuò)誤頁(yè)面放在靜態(tài)資源目錄(如“classpath:/static/”等)下的/error目錄中,而將動(dòng)態(tài)的頁(yè)面模板放在/resources/templates/error目錄下,且動(dòng)態(tài)頁(yè)面模板的優(yōu)先級(jí)更高。接下來(lái)通過(guò)實(shí)例講解在SpringBoot中,如何自定義錯(cuò)誤頁(yè)面。1.簡(jiǎn)單配置2.復(fù)雜配置374.6.2自定義錯(cuò)誤頁(yè)1.簡(jiǎn)單配置

新建chapter04error的項(xiàng)目,在src/main/resources/static目錄下創(chuàng)建error目錄,在該error目錄中創(chuàng)建錯(cuò)誤展示頁(yè)面404.html和500.html,不同的錯(cuò)誤直接展示不同的頁(yè)面,在兩個(gè)頁(yè)面的body標(biāo)簽部分,分別顯示“404錯(cuò)誤!”和“500錯(cuò)誤!”。

新建HelloController的控制器類,代碼如下:

啟動(dòng)項(xiàng)目,在瀏覽器中輸入一個(gè)不存在的路徑時(shí),就會(huì)展示404.html頁(yè)面的內(nèi)容,如圖4-14所示。瀏覽器中輸入正確請(qǐng)求,但請(qǐng)求對(duì)應(yīng)的方法會(huì)拋出異常,就會(huì)展示500.html中的內(nèi)容,如圖4-15所示。38@RestControllerpublicclassHelloController{

@GetMapping("/hello")

publicStringhello(){

inti=1/0; //拋出異常

return"Hello";}}4.6.2自定義錯(cuò)誤頁(yè)

若采用視圖模板技術(shù),則可向用戶展示更多的錯(cuò)誤信息。這里我們以Thymeleaf為例,Thymeleaf頁(yè)面模板默認(rèn)位于classpath:/templates/目錄下,并在該目錄下創(chuàng)建error目錄,在該error目錄下創(chuàng)建錯(cuò)誤展示頁(yè)面4xx.html、5xx.html,以4xx.html頁(yè)面為例,代碼如下所示。SpringBoot在這里一共返回了6條錯(cuò)誤相關(guān)信息,分別是timestamp、status、error、message、path和trace。5xx.html的頁(yè)面內(nèi)容與4xx.html頁(yè)面的內(nèi)容一致。39<!DOCTYPEhtml><htmllang="en"xmlns:th=""><head>

<metacharset="UTF-8">

<title>Title</title>

</head>

<body>

<h3>錯(cuò)誤信息</h3>

<tableborder="1">

<tr><td>timestamp</td><tdth:text="${timestamp}">錯(cuò)誤</td></tr>

<tr><td>status</td><tdth:text="${status}">錯(cuò)誤</td></tr>

<tr><td>error</td><tdth:text="${error}">錯(cuò)誤</td></tr>

<tr><td>message</td><tdth:text="${message}">錯(cuò)誤</td></tr>

<tr><td>path</td><tdth:text="${path}">錯(cuò)誤</td></tr><tr><td>trace</td><tdth:text="${trace}">錯(cuò)誤</td></tr>

</table>

</body>

</html>4.6.2自定義錯(cuò)誤頁(yè)在perties配置文件中,添加配置如下。

先刪除/resources/static/error目錄下的404.html和500.html頁(yè)面文件。啟動(dòng)chapter04error項(xiàng)目,在瀏覽器中輸入一個(gè)不存在的路徑,例如http://localhost:8080/hel,如圖4-16所示。如果訪問(wèn)一個(gè)會(huì)拋出異常的請(qǐng)求,例如http://localhost:8080/hello,如圖4-17所示。

提示:若定義了多個(gè)錯(cuò)誤頁(yè)面,則404.html、500.thml頁(yè)面的優(yōu)先級(jí)高于4xx.html、5xx.html頁(yè)面,動(dòng)態(tài)頁(yè)面的優(yōu)先級(jí)高于靜態(tài)頁(yè)面。40#指定啟動(dòng)錯(cuò)誤頁(yè)面(這是默認(rèn)值)server.error.whitelabel.enabled=true

#指定一直顯示message

server.error.include-message=always

#指定包含異常類

server.error.include-exception=true

#指定一致包含BindingErrors

server.error.include-binding-errors=always

#指定一直包含異常跟蹤棧

server.error.include-stacktrace=always4.6.2自定義錯(cuò)誤頁(yè)2.復(fù)雜配置簡(jiǎn)單配置的方式不夠靈活,只能定義HTML頁(yè)面,展示SpringBoot默認(rèn)的返回信息,無(wú)法處理JSON的定制,無(wú)法返回自定義業(yè)務(wù)數(shù)據(jù),SpringBoot中支持對(duì)Error信息定制。(1)自定義Error數(shù)據(jù)自定義Error數(shù)據(jù)就是對(duì)返回的數(shù)據(jù)進(jìn)行自定義。在項(xiàng)目的src/main/java/目錄下的com.yzpc包中創(chuàng)建名為customerror的包,并在該包中新建一個(gè)MyErrorAttribute類并繼承DefaultErrorAttributes,重寫(xiě)getErrorAttributes方法,代碼如下所示。41@Component//將該類注冊(cè)到Spring容器中

publicclassMyErrorAttributeextendsDefaultErrorAttributes{

@Override

publicMap<String,Object>getErrorAttributes(WebRequestwebRequest,ErrorAttributeOptionsoptions){

//獲取SpringBoot默認(rèn)提供的錯(cuò)誤信息

Map<String,Object>errorAttributes=

super.getErrorAttributes(webRequest,options);

errorAttributes.put("myerror","程序出錯(cuò),錯(cuò)誤如下");//自定義Error

errorAttributes.remove("error");//移除默認(rèn)的error

returnerrorAttributes;

}

}4.6.2自定義錯(cuò)誤頁(yè)

修改4xx.html和5xx.html頁(yè)面,將“錯(cuò)誤信息”的標(biāo)題行,使用自定義的myerror的錯(cuò)誤信息提示,代碼如下所示:重新啟動(dòng)項(xiàng)目,在瀏覽器地址欄中訪問(wèn)http://localhost:8080/hel,如圖4-18所示。訪問(wèn)一個(gè)不存在的路徑或者拋出異常的訪問(wèn)請(qǐng)求,就可以看到自定義的標(biāo)題信息,并且可以看到默認(rèn)的error的數(shù)據(jù)被移除了。42

<h3th:text="${myerror}">錯(cuò)誤信息</h3>

<!--其余代碼一致,此處省略-->

4.6.2自定義錯(cuò)誤頁(yè)(2)自定義Error視圖

自定義Error視圖是展示給用戶的頁(yè)面。

在項(xiàng)目的src/main/java/目錄下的com.yzpc.customerror包中,新建MyErrorViewResolver類,代碼如下所示。

在/resources/templates目錄下新建error.html頁(yè)面,頁(yè)面代碼與前面4xx.html的代碼一致。將MyErrorAttribute類前的@Component注解注釋掉或刪除MyErrorAttribute類。

重新啟動(dòng)項(xiàng)目,無(wú)論發(fā)生的4xx錯(cuò)誤,還是發(fā)生5xx錯(cuò)誤,都是來(lái)到的error.html頁(yè)面。如圖4-19所示。43@Component//將該類注冊(cè)到Spring容器中

publicclassMyErrorViewResolverimplementsErrorViewResolver{

@Override//Map參數(shù)是默認(rèn)的Error信息

publicModelAndViewresolveErrorView(HttpServletRequestrequest,HttpStatusstatus,Map<String,Object>model){

ModelAndViewmav=newModelAndView("error");

mav.addObject("myerror","Error視圖,程序出錯(cuò),錯(cuò)誤如下");

mav.addAllObjects(model);

returnmav;

}

}4.6.2自定義錯(cuò)誤頁(yè)(3)完全自定義前面簡(jiǎn)單配置和復(fù)雜配置兩種自定義方式都是對(duì)BasicErrorController類中的某個(gè)環(huán)節(jié)進(jìn)行修改。開(kāi)發(fā)者需要更加靈活地對(duì)Error視圖和數(shù)據(jù)進(jìn)行處理,可以提供自己的ErrorController。一種是實(shí)現(xiàn)ErrorController接口,該接口只提供了待實(shí)現(xiàn)的方法;另一種直接繼承BasicErrorController,該類已經(jīng)實(shí)現(xiàn)了一些功能,這里通過(guò)繼承BasicErrorController來(lái)實(shí)現(xiàn)自己的ErrorController。在項(xiàng)目的src/main/java/目錄下的com.yzpc.customerror包中,新建MyErrorController類,具體實(shí)現(xiàn)代碼如下所示。44@Controller//將類注冊(cè)到SpringMVC中

publicclassMyErrorControllerextendsBasicErrorController{

@Autowired//注入所需參數(shù)

publicMyErrorController(ErrorAttributeserrorAttributes,ServerPropertiesserverProperties,List<ErrorViewResolver>errorViewResolvers){

super(errorAttributes,serverProperties.getError(),errorViewResolvers);

}

@Override

publicModelAndViewerrorHtml(HttpServletRequestrequest,HttpServletResponseresponse){

HttpStatusstatus=getStatus(request);

Map<String,Object>model=getErrorAttributes(request,getErrorAttributeOptions(request,MediaType.TEXT_HTML));

model.put("myerror","訪問(wèn)出錯(cuò)了!");

ModelAndViewmav=newModelAndView("errorpage",model,status);

returnmav;

}

@Override

publicResponseEntity<Map<String,Object>>error(HttpServletRequestrequest){

Map<String,Object>body=getErrorAttributes(request,getErrorAttributeOptions(request,MediaType.ALL));

body.put("myerror","訪問(wèn)出錯(cuò)啦!");

HttpStatusstatus=getStatus(request);

returnnewResponseEntity<>(body,status);

}

}4.6.2自定義錯(cuò)誤頁(yè)

在resources/templates目錄下新建errorpage.html頁(yè)面,頁(yè)面代碼與前面error.html的代碼一致。重新啟動(dòng)項(xiàng)目,訪問(wèn)一個(gè)不存在的頁(yè)面,就可以看到自定義的錯(cuò)誤信息了,如圖4-20所示。

如果通過(guò)postman發(fā)起這個(gè)請(qǐng)求,那么返回?cái)?shù)據(jù)為一段JSON,如圖4-21所示。SpringBoot雖然提供了非常豐富的自動(dòng)化配置方案,但是也允許開(kāi)發(fā)者根據(jù)實(shí)際情況進(jìn)行完全的自定義,在開(kāi)發(fā)時(shí)可以結(jié)合具體情況選擇合適的Error處理方案。454.6.3在SpringMVC外部映射錯(cuò)誤頁(yè)面對(duì)于不使用SpringMVC的應(yīng)用程序,可以使用errorpageregister接口直接注冊(cè)ErrorPages。這種抽象直接與底層的嵌入式Servlet容器一起工作,即使沒(méi)有SpringMVCDispatcherServlet也可以工作,示例代碼如下所示。如果注冊(cè)了一個(gè)帶有最終由過(guò)濾器處理的路徑的ErrorPage(這在一些非Springweb框架中很常見(jiàn),如Jersey和Wicket),那么過(guò)濾器必須顯式注冊(cè)為錯(cuò)誤調(diào)度器,如下例所示。46@Bean

publicErrorPageRegistrarerrorPageRegistrar(){

returnnewMyErrorPageRegistrar();

}

//...

privatestaticclassMyErrorPageRegistrarimplements

ErrorPageRegistrar{

@Override

publicvoidregisterErrorPages(ErrorPageRegistry

registry){

registry.addErrorPages(newErrorPage

(HttpStatus.BAD_REQUEST,"/400"));

}

}@BeanpublicFilterRegistrationBeanmyFilter(){

FilterRegistrationBeanregistration=newFilterRegistrationBean();

registration.setFilter(newMyFilter());

...

registration.setDispatcherTypes(EnumSet.allOf

(DispatcherType.class));

returnregistration;

}4.7CORS支持CORS(Cross-originresourcesharing)即跨域資源共享,是由W3C制定的一種跨域資源共享技術(shù)標(biāo)準(zhǔn),其目的就是為了解決前端的跨域請(qǐng)求,它允許瀏覽器向跨域服務(wù)器發(fā)送Ajax請(qǐng)求,打破了Ajax只能訪問(wèn)本站內(nèi)的資源限制,CORS在很多地方都有被使用,微信支付的JS支付就是通過(guò)JS向微信服務(wù)器發(fā)送跨域請(qǐng)求。開(kāi)放Ajax訪問(wèn)可被跨域訪問(wèn)的服務(wù)器大大減少了后臺(tái)開(kāi)發(fā)的工作,前后臺(tái)工作也可以得到很好的明確以及分工,下面通過(guò)示例來(lái)講解CORS。(1)新建一個(gè)SpringBoot工程chapter04cors,Group和Packagename為com.yzpc,選擇SpringWeb依賴。

在perties配置文件中設(shè)置端口為8081。

47server.port=80814.7CORS支持(2)在chapter04cors工程中,在src/main/java/目錄下的com.yzpc包中創(chuàng)建名為controller的包,并在該包下創(chuàng)建一個(gè)HelloController的控制器類,代碼如下所示。

在項(xiàng)目的src/main/java/目錄下的com.yzpc包中,創(chuàng)建名為config的包,并在該包下創(chuàng)建一個(gè)MyWebMvcConfig的類,并實(shí)現(xiàn)WebMvcConfigurer接口,重寫(xiě)其中的addCorsMappings方法,代碼如下所示。

上面兩種配置方式@CrossOrigin注解配置和全局配置,選擇其中一種即可,啟動(dòng)chapter04cors工程。48@RestControllerpublicclassHelloController{

@GetMapping("/hello")

//使用@CrossOrigin注解允許跨域

@CrossOrigin(origins="http://localhost:8082",maxAge=1800,allowedHeaders="*")

publicStringhello(){

return"hellocors!";}}@ConfigurationpublicclassMyWebMvcConfigimplementsWebMvcConfigurer{

@Override

publicvoidaddCorsMappings(CorsRegistryregistry){

registry.addMapping("/**")

.allowedOrigins("http://localhost:8082")

.allowedHeaders("*")

.allowedMethods("*")

.maxAge(30*1000);

}

}4.7CORS支持(3)選中chapter04cors工程,右鍵選擇New

Module,新建一個(gè)名為cors的Module,過(guò)程與新建工程類似。在cors中,在src/main/resources/static目錄下,新建index.html網(wǎng)頁(yè)文件和一個(gè)js目錄,并將jquery-3.6.0.js文件放入js目錄下,如圖4-22所示。

靜態(tài)網(wǎng)頁(yè)文件index.html的代碼如下所示。修改perties配置文件,將端口改為8082,如下所示:server.port=8082

啟動(dòng)CorsApplication,在瀏覽器中輸入http://localhost:8082/index.html,頁(yè)面顯示一個(gè)“跨域請(qǐng)求”按鈕,單擊按鈕,就能看到“hellocors!”請(qǐng)求結(jié)果,如圖4-23所示。49<!DOCTYPEhtml><htmllang="en"><head>

<metacharset="UTF-8">

<title>跨域訪問(wèn)示例</title>

<scriptsrc="js/jquery-3.6.0.js"></script>

<script>

functiongetData(){

$.get('http://localhost:8081/hello',function(msg){

$("#app").html(msg);

})

}

</script>

</head>

<body>

<divid="app"></div>

<inputtype="button"value="跨域請(qǐng)求"onclick="getData

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論