一、引言
1.1 初始化配置
為了使用SSM框架去開發,准備SSM框架的模板配置。
1.2 整合第三方框架
為了Spring整合第三方框架,單獨的去編寫xml文件。
1.3 后期維護
后期SSM項目后期xml文件特別多,維護xml文件的成本是很高的
1.4 部署工程
SSM工程部署也是很麻煩,依賴第三方的容器
1.5 敏捷式開發
基於Java的SSM開發方式是很笨重,而現在的python,php,NodeJS的敏捷式開發已經蓋過Java一頭
二、SpringBoot介紹
SpringBoot是由Pivotal團隊研發的,SpringBoot並不是一門新技術,只是將之前常用的Spring,SpringMVC,data-jpa等常用的框架封裝到了一起,幫助你隱藏這些框架的整合細節,實現敏捷開發。
SpringBoot就是一個工具集。
LOGO |
---|
![]() |
SpringBoot特點:
- SpringBoot項目不需要模板化的配置。
- SpringBoot中整合第三方框架時,只需要導入相應的starter依賴包,就自動整合了。
- SpringBoot默認只有一個.properties的配置文件,不推薦使用xml,后期會采用.java的文件去編寫配置信息。
- SpringBoot工程在部署時,采用的是jar包的方式,內部自動依賴Tomcat容器,提供了多環境的配置。
- 后期要學習的微服務框架SpringCloud需要建立在SpringBoot的基礎上。
2.1 約定優於配置
這是形容springBoot最常用的描述,也有人解讀為:約定大於配置,約定好於配置,習慣大於配置等。
用springBoot框架開發程序時,框架提供的默認值會讓我們的項目開發起來效率更快,如果默認值滿足不了我們的需求,我們可以使用Properties配置文件和YAML配置文件來重寫默認值來滿足我們的需求,所以約定大於配置,是說通過約定來較少配置,從而提升開發效率。
而且約定大於配置,並不是一種新的思想,在JDK5.0發布,采用元數據 ,引入注解的概念(也稱之為標注),就代表簡化配置的開始,就是初期的一種 “約定優於配置” 的體現;所以約定優於配置這一設計理念,從 Spring 的注解版本就已經開始了。引入注解就是為了減少一些默認配置,引入注解也就代表着簡化配置的開始,官方說基於 spring 的基礎就是這個事實。
2.2 SpringBoot中的約定
1、Maven的目錄結構。默認有resources文件夾,存放資源配置文件。src-main-resources,src-main-java。默認的編譯生成的類都在targe文件夾下面
2、spring boot默認的配置文件必須是,也只能是application.命名的yml文件或者properties文件,且唯一
3、application.yml中默認屬性。數據庫連接信息必須是以spring: datasource: 為前綴;多環境配置。該屬性可以根據運行環境自動讀取不同的配置文件;端口號、請求路徑等
4、SpringBoot 約定,當你導入 spring-boot-starter-web 后,就約定了你是一個 web 開發環境。就約定了你會使用 SpringMVC。至於其它的也約定你會需要,都給你默認導入進來。當你覺得不合適的時候,可以用更少的改動,滿足你的需要。
5、當我們導入spring-boot-starter-web后,就會自動幫我們導入springMVC的相關依賴和一個內置的tomcat容器,以及spring-boot-starter-logging依賴。這使得在開發階段可以直接通過 main 方法或是 JAR 包獨立運行一個 WEB 項目。
6、SpringBoot 約定以 starter 的形式減少依賴,於是相繼推出了不少常用的 starter。
三、SpringBoot快速入門【重點
】
3.1 快速構建SpringBoot
3.1.1 選擇構建項目的類型
選擇構建項目的類型 |
---|
![]() |
3.1.2 項目的描述
項目的描述 |
---|
![]() |
3.1.3 指定SpringBoot版本和需要的依賴
指定SpringBoot版本和需要的依賴 |
---|
![]() |
3.1.4 導入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 將上述內容修改為下面的效果 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3.1.5 編寫了Controller
@RestController
public class TestController {
@GetMapping("/test")
public String test(){
return "Hello SpringBoot!";
}
}
3.1.6 測試
效果 |
---|
![]() |
3.2 SpringBoot的目錄結構
3.2.1 pom.xml文件
- 指定了一個父工程: 指定當前工程為SpringBoot,幫助我們聲明了starter依賴的版本。
- 項目的元數據:包名,項目名,版本號。
- 指定了properties信息:指定了java的版本為1.8
- 導入依賴:默認情況導入spring-boot-starter,spring-boot-starter-test
- 插件:spring-boot-maven-plugin
3.2.2 .gitignore文件
默認幫我們忽略了一些文件和目錄,避免提交到Git倉庫中
3.2.3 src目錄
-src
-main
-java
-包名
啟動類.java # 需要將controller類,放在啟動類的子包中或者同級包下
-resources
-static # 存放靜態資源的
-templates # 存儲模板頁面的
application.properties # SpringBoot提供的唯一的配置文件
-test # 只是為了測試用的
3.3 SpringBoot三種啟動方式
3.3.1 運行啟動類的main方法
運行main方法即可
3.3.2 maven命令
mvn spring-boot:run
3.3.3 采用jar包的方式運行
將當前項目打包成一個jar文件,並通過java -jar jar文件
3.3.5 采用war包的方式運行
pom配置
<artifactId>day64-sboot-01-mybatis-tx</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 移除嵌入式tomcat插件 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加servlet支持-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!--添加Tomcat-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
修改主啟動類配置
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Day64Sboot01MybatisTxApplication.class);
}
}
原理是該項目被打成war包后放入到webapps下面,tomat啟動的時候就會調用這個方法,從而初始化項目。這個類要和SpringBoot的主啟動類放在一起。
打包
mvn package
四、SpringBoot常用注解【重點
】
4.1 @Configuration和@Bean
之前使用SSM去開發時,在xml文件中編寫bean標簽,但是SpringBoot不推薦使用xml文件。
@Configuration注解相當於beans標簽
@Bean注解相當於bean標簽
id=“方法名 | 注解中的name屬性(優先級更高)”
class=“方法的返回結果”
@Configuration // 代表當前類是一個配置類
public class UserConfig {
@Bean(name = "user1") // 構建一個實例,放到spring容器中
public User user(){
User user = new User();
user.setId(1);
user.setName("張三");
return user;
}
/*
<beans ....> @Configuration
<bean id="user1" class="com.lq.firstspringboot.entity.User" />
</beans>
*/
}
4.2 @SpringBootApplication
@SpringBootApplication就是一個組合注解:
- @SpringBootConfiguration就是@Configuration注解,代表啟動類就是一個配置類。
- @EnableAutoConfiguration幫你實現自動裝配的,SpringBoot工程啟動時,運行一個SpringFactoriesLoader的類,加載META-INF/spring.factories配置類(已經開啟的),通過SpringFactoriesLoader中的load方法,以for循環的方式,一個一個加載。
- 好處:無需編寫大量的整合配置信息,只需要按照SpringBoot提供好了約定去整合即可。
- 壞處:如果說你導入了一個starter依賴,那么你就需要填寫他必要的配置信息。
- 手動關閉自動裝配指定內容:@SpringBootApplication(exclude = QuartzAutoConfiguration.class)
- @ComponentScan就相當於<context:component-scan basePackage=“包名” />,幫助掃描注解的。
五、SpringBoot常用配置【重點
】
5.1 SpringBoot的配置文件格式
SpringBoot的配置文件支持properties和yml,甚至他還支持json。
更推薦使用yml文件格式:
yml文件,會根據換行和縮進幫助咱們管理配置文件所在位置
yml文件,相比properties更輕量級一些
yml文件的劣勢:
嚴格遵循換行和縮進
在填寫value時,一定要在: 后面跟上空格
applicaiton.properties
user.username=root
#時間
user.birthday=2016-12-12
#數組
user.loves[0]=book
user.loves[1]=code
user.loves[2]=java
#list
user.emails[0]=a@qf.com
user.emails[1]=b@qf.com
user.emails[2]=c@qf.commo
#map
user.userMap[k1]=v1
user.userMap[k2]=v2
application.yml
server:
port: 8888
servlet:
context-path: /abc
user:
username: 張三
loves:
- java
- book
id: 10
emails:
- a1@qf.com
- a2@qf.com
userMap:
k1: v1
k2: v2
birthda: 2019-12-12
User.java
@Data
@Component
@ConfigurationProperties(prefix = "user")
public class User {
private Integer id;
private String username;
private String loves[];
private List<String> emails;
private Map<String,String> userMap;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
}
5.2 多環境配置
在application.yml文件中添加一個配置項:
spring:
profiles:
active: 環境名
在resource目錄下,創建多個application-環境名.yml文件即可
在部署工程時,通過 java -jar jar文件 --spring.profiles.active=環境
5.3 引入外部配置文件信息
和傳統的SSM方式一樣,通過@Value的注解去獲取properties/yml文件中的內容。
如果在yml文件中需要編寫大量的自定義配置,並且具有統一的前綴時,采用如下方式
// Java程序
@ConfigurationProperties(prefix = "aliyun")
@Component
@Data
public class AliyunProperties {
private String xxxx;
private ... ...;
}
// 配置文件
aliyun:
xxxx: xxxxxxxxx
...
5.4 熱加載
5.4.1 導入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
5.4.2 settings配置
修改settings中的配置 |
---|
![]() |
5.4.3 重新構建工程
build |
---|
![]() |
六、SpringBoot整合Mybatis【重點
】
6.1 xml方式整合Mybatis
xml方式在編寫復雜SQL時,更適合
6.1.1 導入依賴。
<!-- mysql驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid連接-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
6.1.2 編寫配置文件
// 准備實體類
@Data
public class Air implements Serializable {
private Integer id;
private Integer districtId;
private java.util.Date monitorTime;
private Integer pm10;
private Integer pm25;
private String monitoringStation;
private java.util.Date lastModifyTime;
}
// ================================================
@Data
public class District implements Serializable {
private Integer id;
private String name;
}
6.1.3 准備Mybatis
// 1. 接口
public interface AirMapper {
List<Air> findAll();
}
// 2. 在啟動類中添加直接,掃描Mapper接口所在的包
@MapperScan(basePackages = "com.lq.firstspringboot.mapper")
// 3. 准備映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lq.firstspringboot.mapper.AirMapper">
<!-- List<Air> findAll();-->
<select id="findAll" resultType="Air">
select * from air
</select>
</mapper>
yml配置文件
spring:
datasource: # 連接數據庫的信息
url: jdbc:mysql://localhost:3306/2001
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
mybatis: # mybatis配置
type-aliases-package: com.lq.sboothellowar.entity
mapper-locations: mapper/*.xml
logging: # 日志配置
level:
com.lq.sboothellowar.mapper: debug
6.1.4 測試。
class AirMapperTest extends FirstSpringbootApplicationTests {
@Autowired
private AirMapper airMapper;
@Test
void findAll() {
List<Air> list = airMapper.findAll();
for (Air air : list) {
System.out.println(air);
}
}
}
6.2 注解方式整合Mybatis
注解方式在編寫配置簡單,簡單SQL推薦使用
6.2.1 創建District的Mapper接口
public interface DistrictMapper {
List<District> findAll();
}
6.2.2 添加Mybatis注解
針對增刪改查:@Insert,@Delete,@Update,@Select
還是需要在啟動類中添加@MapperScan注解
@Select("select * from district")
List<District> findAll();
@Select("select * from district where id = #{id}")
District findOneById(@Param("id") Integer id);
6.2.3 添加配置
// yml文件
logging:
level:
com.lq.firstspringboot.mapper: DEBUG
6.2.4 測試,查看日志
class DistrictMapperTest extends FirstSpringbootApplicationTests {
@Autowired
private DistrictMapper mapper;
@Test
void findAll() {
List<District> list = mapper.findAll();
for (District district : list) {
System.out.println(district);
}
}
@Test
void findOneById() {
District district = mapper.findOneById(5);
System.out.println(district);
}
}
6.3 SpringBoot整合MyBatis-Plus
6.3.1 導入依賴
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>2.3</version>
</dependency>
6.3.2 yml配置
mybatis-plus:
type-aliases-package: com.lq.entity
# mapper-locations: mapper文件
6.3.3開啟dao層掃描
@SpringBootApplication(scanBasePackages = "com.lq")
@MapperScan(basePackages = "com.lq.dao")
public class SbootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SbootDemoApplication.class, args);
}
}
6.3.4 注解
@Data
@TableName("emp")
public class Emp {
@TableId(type = IdType.AUTO) // 主鍵 自動遞增
private long empno;
@TableField("name") // username對應表中是name
private String username;
@TableField(exist = false)
private List<String> list; // 表中不存在這個屬性
6.3.5 開啟分頁
@Component
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
6.3.6 測試
@Test
void testPage(){
Page<Emp> page = new Page<>();
page.setSize(5);
page.setCurrent(1);
List<Emp> emps = empMapper.selectPage(page, null);
page.setRecords(emps);
System.out.println(page);
}
6.3.7事務控制
@EnableTransactionManagement // 用注解來控制事務
@SpringBootApplication
@MapperScan(basePackages = "com.lq.mapper")
@ComponentScan(basePackages = "com.lq")
public class Springboot01Application {
public static void main(String[] args) {
SpringApplication.run(Springboot01Application.class, args);
}
}
七、SpringBoot提供視圖支持
Spring Boot支持多種模版引擎包括:
FreeMarker(*.ftm)
Groovy
Thymeleaf(官方推薦)
Mustache
JSP技術Spring Boot官方是不推薦的原因有:
tomcat只支持war的打包方式,不支持可執行的jar。
Jetty 嵌套的容器不支持jsp
當你使用上述模板引擎中的任何一個,它們默認的模板配置路徑為:src/main/resources/templates。當然也可以修改這個路徑,具體如何修改,可在后續各模板引擎的配置屬性中查詢並修改
Thymeleaf模板引擎
Thymeleaf是一款用於渲染XML/XHTML/HTML5內容的模板引擎。類似JSP,FreeMaker等,它也可以輕易的與Spring MVC等Web框架進行集成作為Web應用的模板引擎。與其它模板引擎相比,Thymeleaf最大的特點是能夠直接在瀏覽器中打開並正確顯示模板頁面,而不需要啟動整個Web應用。它的功能特性如下:
Spring MVC中@Controller中的方法可以直接返回模板名稱
模板中的表達式支持Spring表達式語言(Spring EL)
表單支持,並兼容Spring MVC的數據綁定與驗證機制
國際化支持
7.1 JSP視圖
7.1.1 需要導入依賴
<!-- JSP核心引擎依賴-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- JSTL-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
7.1.2 創建JSP頁面
創建webapp以及WEB-INF去存放JSP頁面 |
---|
![]() |
7.1.3 創建Contorller
// Controller
@Controller
public class JspController {
@GetMapping("/index")
public String index(Model model){
model.addAttribute("name","張三");
return "index";
}
}
7.1.4 配置前綴和后綴
spring:
mvc:
# 視圖的前綴和后綴
view:
prefix: /WEB-INF/
suffix: .jsp
7.2 Thymeleaf視圖
7.2.1 依賴
<!-- thymeleaf 視圖模板-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
7.2.2 yml配置
spring:
thymeleaf:
cache: fase
7.2.3 使用thymeleaf
// 1.引入命名空間
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
// 2.從域對象中取值
req:<span th:text="${reqKey}"></span><br>
session:<span th:text="${session.sessionKey}"></span><br>
application:<span th:text="${application.applicationKey}"></span><br>
內置對象:<span th:text="${#request.getAttribute('reqKey')}"></span>
// 3.thymeleaf其他常用操作
<base th:href="${#request.getContextPath()+'/'}">
<td th:text="${#dates.format(user.createTime,'yyyy-MM-dd')}"></td>
<input type="hidden" name="id" th:value="${user.id}" >
th:onclick="|admin_edit('user/getUserById/${user.id}')|"
<p class="miaoshu" th:utext="${goods.ginfo}"></p>
<tr th:each="topic:${page.list}">
<span th:text="${sex ==1?'男':'女'}"></span>
<span th:text="${#numbers.formatDecimal(price,4,3)}"></span>
#numbers.formatDecimal(numbwe,整數位,小數位)。
整數位表示,整數位不足四位,用0補齊
<img th:each="img:${#strings.listSplit(gg.gimage,'|')}" th:src="${img}">
<div th:switch="${age}">
<p th:case="10">10歲</p>
<p th:case="20">20歲</p>
<p th:case="*">大於30歲(默認值)</p>
</div>
<script th:inline="javascript">
var message = [[${user.username}]];
var username=[[${#request.getParameter('returnUrl')}]];
console.log(message);
</script>
7.2.4 修改html模板
7.2.5 thymeleaf其他屬性
#開啟模板緩存(默認值:true)
spring.thymeleaf.cache=true
#在呈現模板之前,檢查模板是否存在
spring.thymeleaf.check-template=true
#檢查模板位置是否正確(默認值:true)
spring.thymeleaf.check-template-location=true
#Content-Type的值(默認值:text/html)
spring.thymeleaf.content-type=text/html
#開啟MVC Thymeleaf視圖解析(默認值:true)
spring.thymeleaf.enabled=true
#模板編碼
spring.thymeleaf.encoding=UTF-8
#要被排除在解析之外的視圖名稱列表,用逗號分隔
spring.thymeleaf.excluded-view-names=
#要運用於模板之上的模板模式。另見StandardTemplate-ModeHandlers(默認值:HTML5)
spring.thymeleaf.mode=HTML5
#在構建URL時添加到視圖名稱前的前綴(默認值:classpath:/templates/)
spring.thymeleaf.prefix=classpath:/templates/
#在構建URL時添加到視圖名稱后的后綴(默認值:.html)
spring.thymeleaf.suffix=.html
#Thymeleaf模板解析器在解析器鏈中的順序。默認情況下,它排第一位。順序從1開始,只有在定義了額外的TemplateResolver Bean時才需要設置這個屬性。
spring.thymeleaf.template-resolver-order=
#可解析的視圖名稱列表,用逗號分隔
spring.thymeleaf.view-names=
7.2.6 分頁 (page.html)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:fragment="pageDiv">
<link rel="stylesheet" href="lib/layer/ui/css/layui.css" media="all">
<script src="lib/layer/ui/layui.js"></script>
<div id="pageDiv"></div>
<script th:inline="javascript">
var total = [[${page.total}]];
var pageSizse = [[${page.pageSize}]];
var pageNum = [[${page.pageNum}]];
var url = [[${url}]];
</script>
<script>
layui.use('laypage', function() {
var laypage = layui.laypage;
laypage.render({
elem : 'pageDiv'
,count : total
,limit : pageSizse
,curr:pageNum
,layout : [ 'prev', 'page', 'next', 'limit', 'count' ]
,limits:[5,10,20]
,jump : function(obj, first) {
console.log(obj)
if (!first) {
location.href=url+"?pageNum="+obj.curr+"&pageSize="+obj.limit;
}
}
});
});
</script>
</div>
</body>
</html>
7.2.7 包含
<div th:replace="/common/page::pageDiv"></div> ## 分頁路徑::模板中的ID
八、SpringBoot靜態資源處理
Spring Boot 默認為我們提供了靜態資源處理,使用 WebMvcAutoConfiguration 中的配置各種屬性。
建議大家使用Spring Boot的默認配置方式,提供的靜態資源映射如下:
classpath:/META-INF/resources
classpath:/resources
classpath:/static
classpath:/public
上面這幾個都是靜態資源的映射路徑,優先級順序為:META-INF/resources > resources > static > public。
可以隨機在上面一個路徑下面放上index.html,當我們訪問應用根目錄http://lcoalhost:8080 時,會直接映射到index.html頁面。
九、SpringBoot自定義靜態資源處理
如果Spring Boot提供的Sping MVC不符合要求,則可以通過一個配置類(注解有@Configuration的類)加上@EnableWebMvc注解來實現完全自己控制的MVC配置。
當然,通常情況下,Spring Boot的自動配置是符合我們大多數需求的。在你既需要保留Spring Boot提供的便利,有需要增加自己的額外的配置的時候,可以定義一個配置類並繼承WebMvcConfigurer,無需使用@EnableWebMvc注解。
這里我們提到這個WebMvcConfigurerAdapter這個類,重寫這個類中的方法可以讓我們增加額外的配置,這里我們就介紹幾個常用的。
@Configuration
public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer {
/**
* 配置靜態資源訪問
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
System.out.println("MyWebMvcConfigurerAdapter.addResourceHandlers");
registry.addResourceHandler("/a/**").addResourceLocations("classpath:/a/");
}
}
addResoureHandler指的是對外暴露的訪問路徑
ddResourceLocations指的是文件放置的目錄
十、頁面跳轉
@Configuration
public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
System.out.println("MyWebMvcConfigurerAdapter.addViewControllers");
registry.addViewController("toLogin").setViewName("login");
}
}
十一、.攔截器
寫一個攔截器實現HandlerInterceptor接口
@Configuration
public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new loginInterceprot())
.addPathPatterns("/**") // 被攔截路徑
.excludePathPatterns("/toLogin"); // 忽略路徑
}
}
十二、SpringBoot全局異常處理
默認情況下,Spring Boot為兩種情況提供了不同的響應方式。一種是瀏覽器客戶端請求一個不存在的頁面或服務端處理發生異常時,一般情況下瀏覽器默認發送的請求頭中Accept: text/html,所以Spring Boot默認會響應一個html文檔內容,稱作“Whitelabel Error Page”。另一種是使用Postman等調試工具發送請求一個不存在的url或服務端處理發生異常時,Spring Boot會返回類似如下的Json格式字符串信息
出現異常響應頁面
直接在/resources/templates下面創建error.html就可以覆蓋默認的Whitelabel Error Page的錯誤頁面
<!DOCTYPE html >
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
錯誤頁面
<p th:text="${error}"></p>
<p th:text="${status}"></p>
<p th:text="${message}"></p>
</body>
</html>
出現異常響應JSON數據
@ControllerAdvice
public class ExceptionHanlder {
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Map<String, String> exceptionToJSON(Exception e) {
System.out.println("ExceptionHanlder.exceptionToJSON");
// 1.先封裝異常信息提示給用戶
Map<String, String> map = new HashMap<String, String>();
map.put("code", "500");
map.put("message", "服務端異常");
// 2.紀錄異常信息
// log.error("出現異常了", e);
return map;
}
}
十三、springMvc的RestTemplate服務器間的請求
使用Restful風格發送數據
發送端
/**
* 測試rest風格地址欄傳遞參數
*/
@Test
public void testRest(){
String result = restTemplate.getForObject("http://localhost:8082/search/getEmpById/200", String.class);
System.out.println("result:"+result);
}
接收端
/**
* 接收RESTful風格,地址欄傳值
* @return
*/
@RequestMapping("/getEmpById/{id}")
public String getEmpById(@PathVariable Integer id){
System.out.println("id:"+id);
return "getEmpById";
}
普通的請求
發送端
/**
* 只請求,不傳值
*/
@Test
public void testRestTemplate(){
//發送一個請求,地址欄傳值
String result = restTemplate.getForObject("http://localhost:8082/search/hello", String.class);
System.out.println("result"+result);
}
接收端
@RequestMapping("/hello")
public String hello(){
System.out.println("Search.hello");
return "Search Hello";
}
使用Json格式數據發送數據
發送端
/**
* 測試傳遞Json數據參數請求
*/
@Test
public void testJson() throws JsonProcessingException {
//1.創建一個對象
Emp emp = new Emp();
emp.setDeptno(10);
emp.setEname("admin");
emp.setHiredate(new Date());
//2.創建請求頭
HttpHeaders httpHeaders = new HttpHeaders();
//3.設置請求頭的數據類型為application/json
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
//4、封裝請求數據和請求頭
HttpEntity<Emp> entity = new HttpEntity<>(emp,httpHeaders);//數據將會自動轉換為json格式
//5、發送數據
String result = restTemplate.postForObject("http://localhost:8082/search/addEmpFromJson", entity, String.class);
System.out.println("result:"+result);
}
接收端
/**
* 接收Json字符串的參數
* @param emp
* @return
*/
@RequestMapping("/addEmpFromJson")
public String addEmp(@RequestBody Emp emp){
System.out.println("emp:"+emp);
return "addEmpFrom";
}
使用form表單的方式發送數據
發送端
/**
* 表單傳遞數據
*/
@Test
public void testForm(){
//1、表單數據必須要用MultiValueMap封裝
MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
map.add("ename","admin");
map.add("hiredate","2020-12-12");
//2、創建請求頭
HttpHeaders httpHeaders = new HttpHeaders();
//3、設置請求頭的數據類型格式為表單類型
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//4、封裝請求頭和請求數據
HttpEntity<MultiValueMap<String,Object>> httpEntity = new HttpEntity<>( map, httpHeaders);
//5、發送請求
String result = restTemplate.postForObject("http://localhost:8082/search/addEmpByForm", httpEntity, String.class);
System.out.println("result:"+result);
}
接收端
/**
* 接收表單類型數據
* @return
*/
@RequestMapping("/addEmpByForm")
public String addEmpByForm(Emp emp){
System.out.println("emp = [" + emp + "]");
return "addEmpByForm";
}
RestTemplate相對於URL的優缺點
1、數據的傳遞和獲取都非常的方便
2、支持RestFul風格