前言
記錄學(xué)習(xí)過程中中途碰到問題及解決辦法和查找相關(guān)資料的。
現(xiàn)在公司比較流行SpringCloud或阿里的dobbo,這2個(gè)技術(shù)都需要Springboot,因?yàn)镾pringboot在微服務(wù)的基礎(chǔ)。
Beetl模板與thymeleaf模板各有什么優(yōu)勢(shì),應(yīng)該用哪種呢?留后期調(diào)研。
微框架,與Spring4一起誕生,比如SpringMVC中的@RestController,使用它可以在web頁(yè)面直接放回一個(gè)json到web頁(yè)面或app
Springboot可以快速上手,整合了一下子項(xiàng)目(開源框架或第三方開源庫(kù))
Springboot可以依賴很少的配置,就可以十分快速的搭建并運(yùn)行項(xiàng)目。
這里主要采用的基礎(chǔ)項(xiàng)目
Spring Boot 2多模塊 Spring Boot 項(xiàng)目--之多模塊重構(gòu)
項(xiàng)目下載地址
https://yunpan.#/surl_yFtZK2c74HC (提取碼:a184)
涉及到的知識(shí)點(diǎn)
- 構(gòu)建Springboot項(xiàng)目
- Springboot接口返回json及jackson使用
- Springboot熱部署
- Springboot資源屬性配置
- Springboot模板引擎--thymeleaf
- springboot異常處理
Springboot特點(diǎn)
- 基于Spring,使開發(fā)者快速入門,門檻很低。spring的全家桶提供了非常強(qiáng)大的功能。
- Springboot可以創(chuàng)建獨(dú)立運(yùn)行的應(yīng)用,而不依賴與容器。
- 不需要打包成war包,可以放入tomcat中直接運(yùn)行
- Springboot提供manven極簡(jiǎn)配置,不用在看過多的xml(默認(rèn)配置),切點(diǎn)是會(huì)引入狠多你不需要的包
- Springboot提供可視化的相關(guān)功能,方便監(jiān)控,比如性能,應(yīng)用的健康程度。
- Springboot微微服務(wù)SpringCloud鋪路,SpringBoot可以整合很多各式各樣的框架來構(gòu)建微服務(wù),比如dubbo,thrift
構(gòu)建Springboot項(xiàng)目(參考之前的文章)
Spring Boot 1第一個(gè)項(xiàng)目-helloWorld
#官方地址
https://spring.io/
SpringBoot接口返回json及Jackson的基本演繹
#添加數(shù)據(jù)web api方式返回POST
localhost:8080/person/saveApi?name=牽手生活22&age=18&password=123456
#獲取模擬數(shù)據(jù)返回GET
localhost:8080/person/getUserDemo
先看看實(shí)現(xiàn)的效果時(shí)什么樣的,實(shí)現(xiàn)中功能修改了2個(gè)文件User.java、UserController.java,并增加了Api接口外的類IYounghareJsonResult.java(來自github的LeeJSONResult.java)


修改的User.java實(shí)體如下
public class User {
private int id;
private String name;
private int age; //年齡
@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss a",locale = "zh",timezone = "GMT+8")
private Date birthday; //出生年月
@JsonIgnore //json返回時(shí),忽略
private String password; //密碼
@JsonInclude(JsonInclude.Include.NON_NULL) //當(dāng)數(shù)據(jù)為空時(shí)不返回
private String desc; //描述
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
", password='" + password + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
UserController.java增加了saveApi接口
@RestController //表示是一個(gè)Rest接口 ==@Controller+ @ResponseBody(方法位置)
public class UserController {
private final UserRepostory userRepostory; //沒有初始化,這里采用構(gòu)造器注入的方式
@Autowired
public UserController(UserRepostory userRepostory){
this.userRepostory = userRepostory;
}
@PostMapping("/person/save")
//@RequestBody ==采用@RestController 不再需要這個(gè)
public User save(@RequestParam String name,@RequestParam int age,@RequestParam String password){
User user = new User();
user.setName(name);
user.setAge(age);
user.setPassword(password);
user.setBirthday(new Date());
user.setDesc(null);
if (userRepostory.save(user)){
System.out.printf("用戶對(duì)象:%s 保存成功\n",user);
}
return user;
}
@PostMapping("/person/saveApi")
public IYounghareJSONResult saveApi(@RequestParam String name,@RequestParam int age){
User user = new User();
user.setName(name);
user.setAge(age);
user.setBirthday(new Date());
user.setDesc(null);
if (userRepostory.save(user)){
System.out.printf("用戶對(duì)象:%s 保存成功\n",user);
}
//return user;
return IYounghareJSONResult.ok(user);
}
@GetMapping("/person/getUserDemo")
//@RequestBody ==采用@RestController 不再需要這個(gè)
public User getUserDemo(){
User user = new User();
user.setName("牽手");
user.setAge(18);
user.setPassword("123456");
user.setBirthday(new Date());
user.setDesc(null);
return user;
}
}

IYounghareJsonResult.java 工具類代碼
/**
*
* @Title: LeeJSONResult.java
* @Package com.lee.utils
* @Description: 自定義響應(yīng)數(shù)據(jù)結(jié)構(gòu)
* 這個(gè)類是提供給門戶,ios,安卓,微信商城用的
* 門戶接受此類數(shù)據(jù)后需要使用本類的方法轉(zhuǎn)換成對(duì)于的數(shù)據(jù)類型格式(類,或者list)
* 其他自行處理
* 200:表示成功
* 500:表示錯(cuò)誤,錯(cuò)誤信息在msg字段中
* 501:bean驗(yàn)證錯(cuò)誤,不管多少個(gè)錯(cuò)誤都以map形式返回
* 502:攔截器攔截到用戶token出錯(cuò)
* 555:異常拋出信息
* Copyright: Copyright (c) 2016
* Company:Nathan.Lee.Salvatore
*
* @author leechenxiang
* @date 2016年4月22日 下午8:33:36
* @version V1.0
*/
public class IYounghareJSONResult {
// 定義jackson對(duì)象
private static final ObjectMapper MAPPER = new ObjectMapper();
// 響應(yīng)業(yè)務(wù)狀態(tài)
private Integer status;
// 響應(yīng)消息
private String msg;
// 響應(yīng)中的數(shù)據(jù)
private Object data;
private String ok; // 不使用
public static IYounghareJSONResult build(Integer status, String msg, Object data) {
return new IYounghareJSONResult(status, msg, data);
}
public static IYounghareJSONResult ok(Object data) {
return new IYounghareJSONResult(data);
}
public static IYounghareJSONResult ok() {
return new IYounghareJSONResult(null);
}
public static IYounghareJSONResult errorMsg(String msg) {
return new IYounghareJSONResult(500, msg, null);
}
public static IYounghareJSONResult errorMap(Object data) {
return new IYounghareJSONResult(501, "error", data);
}
public static IYounghareJSONResult errorTokenMsg(String msg) {
return new IYounghareJSONResult(502, msg, null);
}
public static IYounghareJSONResult errorException(String msg) {
return new IYounghareJSONResult(555, msg, null);
}
public IYounghareJSONResult() {
}
// public static LeeJSONResult build(Integer status, String msg) {
// return new LeeJSONResult(status, msg, null);
// }
public IYounghareJSONResult(Integer status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public IYounghareJSONResult(Object data) {
this.status = 200;
this.msg = "OK";
this.data = data;
}
public Boolean isOK() {
return this.status == 200;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
/**
*
* @Description: 將json結(jié)果集轉(zhuǎn)化為L(zhǎng)eeJSONResult對(duì)象
* 需要轉(zhuǎn)換的對(duì)象是一個(gè)類
* @param jsonData
* @param clazz
* @return
*
* @author leechenxiang
* @date 2016年4月22日 下午8:34:58
*/
public static IYounghareJSONResult formatToPojo(String jsonData, Class<?> clazz) {
try {
if (clazz == null) {
return MAPPER.readValue(jsonData, IYounghareJSONResult.class);
}
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (clazz != null) {
if (data.isObject()) {
obj = MAPPER.readValue(data.traverse(), clazz);
} else if (data.isTextual()) {
obj = MAPPER.readValue(data.asText(), clazz);
}
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
/**
*
* @Description: 沒有object對(duì)象的轉(zhuǎn)化
* @param json
* @return
*
* @author leechenxiang
* @date 2016年4月22日 下午8:35:21
*/
public static IYounghareJSONResult format(String json) {
try {
return MAPPER.readValue(json, IYounghareJSONResult.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
*
* @Description: Object是集合轉(zhuǎn)化
* 需要轉(zhuǎn)換的對(duì)象是一個(gè)list
* @param jsonData
* @param clazz
* @return
*
* @author leechenxiang
* @date 2016年4月22日 下午8:35:31
*/
public static IYounghareJSONResult formatToList(String jsonData, Class<?> clazz) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (data.isArray() && data.size() > 0) {
obj = MAPPER.readValue(data.traverse(),
MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
public String getOk() {
return ok;
}
public void setOk(String ok) {
this.ok = ok;
}
}
代碼先保存,方便之后修改或提前
https://yunpan.#/surl_yFtcg3T5PvF (提取碼:7df9)
SpringBoot開發(fā)環(huán)境熱部署(可行我好像沒有熱部署成功)
開發(fā)環(huán)境中,如果修改某個(gè)文件,如修改User或、UserController需要重啟服務(wù)器
Springboot使用devtools進(jìn)行熱部署
在pom.xml文件中添加
<!-- 熱部署 -->
<!-- devtools可以實(shí)現(xiàn)頁(yè)面熱部署(即頁(yè)面修改后會(huì)立即生效,
這個(gè)可以直接在application.properties文件中配置spring.thymeleaf.cache=false來實(shí)現(xiàn)) -->
<!-- 實(shí)現(xiàn)類文件熱部署(類文件修改后不會(huì)立即生效),實(shí)現(xiàn)對(duì)屬性文件的熱部署。 -->
<!-- 即devtools會(huì)監(jiān)聽classpath下的文件變動(dòng),并且會(huì)立即重啟應(yīng)用(發(fā)生在保存時(shí)機(jī)),
注意:因?yàn)槠洳捎玫奶摂M機(jī)機(jī)制,該項(xiàng)重啟是很快的 -->
<!-- (1)base classloader (Base類加載器):加載不改變的Class,例如:第三方提供的jar包。 -->
<!-- (2)restart classloader(Restart類加載器):加載正在開發(fā)的Class。 -->
<!-- 為什么重啟很快,因?yàn)橹貑⒌臅r(shí)候只是加載了在開發(fā)的Class,沒有重新加載第三方的jar包。 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<!-- optional=true, 依賴不會(huì)傳遞, 該項(xiàng)目依賴devtools;
之后依賴boot項(xiàng)目的項(xiàng)目如果想要使用devtools, 需要重新引入 -->
<optional>true</optional>
</dependency>
修改application.properties 添加如下內(nèi)容(#開始的是注釋)
#熱部署生效
spring.devtools.restart.enabled=true
#設(shè)置重啟的目錄,添加哪個(gè)目錄的文件需要重啟
spring.devtools.restart.additional-paths=src/main/java
# 為amybatis設(shè)置,生成環(huán)境可以刪除
#restart.include.mapper=/mapper-[\\w-\\.]+jar
#restart.include.pagehelper=/pagehelper-[\\w-\\.]+jar
#排除哪個(gè)目錄的文件不需要重啟
#spring.devtools.restart.exclude=static/**,public/**
#classpath目錄下的WEB-INF文件夾內(nèi)容修改不重啟(靜態(tài)文件的修改不需要重啟)
#spring.devtools.restart.exclude=WEB-INF/**

SpringBoot 資源文件屬性配置application.properties
在pom.xml文件中添加依賴
<!--#資源文件屬性配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
我在使用@configurationProperties注解時(shí) idea彈出 Spring Boot Annotion processor not found in classpath
創(chuàng)建czgResource.properties資源文件、創(chuàng)建Resouce.java類、創(chuàng)建ResourceController.java類

訪問路徑及效果
localhost:8080/resouce/getResouce

czgResource.properties
com.younghare.opensource.name=牽手生活--簡(jiǎn)書
com.younghare.opensource.website=http://www.itdecent.cn/u/e09dc5872735
com.younghare.opensource.desc=筆記整理。分享是一種美德,牽手生活,攜手前行
# spring使用@Value標(biāo)簽讀取.properties文件的中文亂碼問題的解決 https://blog.csdn.net/J3oker/article/details/53839210
CzgResouce.java
@Configuration //表示要引用資源文件的配置
@ConfigurationProperties(prefix="com.younghare.opensource")
@PropertySource(value= "classpath:czgResource.properties")
public class CzgResouce {
private String name;
private String webSite;
private String desc;
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWebSite() {
return webSite;
}
public void setWebSite(String webSite) {
this.webSite = webSite;
}
}
ResourceController.java
@RestController //表示是一個(gè)Rest接口 ==@Controller+ @ResponseBody(方法位置)
public class ResourceController {
@Autowired
private CzgResouce czgResouce;
@RequestMapping("/resouce/getResouce")
public IYounghareJSONResult getCzgResouce(){
CzgResouce bean_Czg_resouce = new CzgResouce();
BeanUtils.copyProperties(czgResouce, bean_Czg_resouce);
return IYounghareJSONResult.ok(bean_Czg_resouce);
}
}
SpringBoot 資源文件配置server以及tomcat及端口
Springboot默認(rèn)是使用tomcat,更多細(xì)節(jié)參考
修改application.properties文件如下:
#####################################################
#
# Server 服務(wù)器端相關(guān)配置
#####################################################
#配置api端口
server.port=8081
#設(shè)定應(yīng)用的context-path,一般來說這個(gè)配置在正式發(fā)布的時(shí)候不配置
#server.servlet.context-path=/IYounghare
#錯(cuò)誤頁(yè)面,指定發(fā)生錯(cuò)誤時(shí),跳轉(zhuǎn)的URL -->BasicErrorController
server.error.path=/error
#session最大超時(shí)時(shí)間(分鐘),默認(rèn)30分鐘
server.servlet.session.timeout=60
#該服務(wù)器綁定IP地址,啟動(dòng)服務(wù)器時(shí)如果本機(jī)不是該IP地址則拋出異常,啟動(dòng)失敗,
#只有特殊需求的情況下才配置,具體根據(jù)各自的業(yè)務(wù)來設(shè)置
#####################################################
#
# Server --tomcat服務(wù)器端相關(guān)配置
#####################################################
#tomcat最大的線程數(shù),默認(rèn)200
#server.tomcat.max-threads=180
#tomcat的URI編碼
server.tomcat.uri-encoding=UTF-8
#存放tomcat的日志,dump等文件的臨時(shí)文件夾,默認(rèn)為系統(tǒng)的tmp文件夾
#如:c:\users\younghare\AppData\Local\Temp\
server.tomcat.accesslog.enabled=true
#server.tomcat.accesslog.pattern=
#accesslog目錄,默認(rèn)在basedir/logs
#server.tomcat.accesslog.directory=
#日志文件目錄
logging.path= D:/czg/czgTemp/springboot-tomcat-tmp
#日志文件名稱,默認(rèn)為spring.log
#logging.file= myapp.log

SpringBoot 整合模板引擎freemarker(略)、thyemleaf
在resources資源下創(chuàng)建templates文件夾

整合thymeleaf
在pom.xml中添加依賴
<!-- 引入 thymeleaf 模板依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
在application.properties 添加thymeleaf的配置信息
#####################################################
#
#thymeleaf 靜態(tài)資源配置
#
#####################################################
#前綴,默認(rèn)文件夾
spring.thymeleaf.prefix=classpath:/templates/
#后綴時(shí).html
spring.thymeleaf.suffix=.html
#模式使用html5
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
#deprecated configuration property spring.thymeleaf.content-type 意思是這個(gè)屬性已經(jīng)過時(shí)不被使用
#spring.thymeleaf.content-type=text/html
#content-type 是text和html
spring.thymeleaf.servlet.content-type=text/html
# 關(guān)閉緩存,即時(shí)刷新,上線生成環(huán)境需要改為true
spring.thymeleaf.cache=false
springboot集成themeleaf報(bào)Namespace 'th' is not bound

ThymeleafController.java
@Controller
@RequestMapping("th_czg") //設(shè)置訪問路徑
public class ThymeleafController {
@RequestMapping("dynamicThymeleaf")
public String dynamicThymeleaf(ModelMap map) {
map.addAttribute("name", "thymeleaf-為什么進(jìn)不了這個(gè)斷點(diǎn)"); ////需要SpringMVC的依賴庫(kù)
return "thymeleaf/dynamicThymeleaf/dynamicThymeleafDemo";
}
@RequestMapping("staticThymeleaf")
public String staticThymeleaf() {
return "thymeleaf/staticThymeleaf/thymeleafDemo";
}
}
thymeleafDemo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Thymeleaf模板引擎--靜態(tài)demo
<h1>thymeleafDemo page</h1>
</body>
</html>
dynamicThymeleafDemo.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head >
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Thymeleaf模板引擎
<!-- 注意: th 等thymeleaf表達(dá)式 ,在直接用瀏覽器打開該html文件時(shí),不會(huì)被加載,只有后臺(tái)有返回對(duì)應(yīng)的值時(shí)才有對(duì)應(yīng)的內(nèi)容-->
<h1 th:text="${name}">hello world~~~~~~~</h1>
</body>
</html>
測(cè)試地址
#測(cè)試靜態(tài)地址
http://localhost:8080/th_czg/staticThymeleaf
#加載動(dòng)態(tài)
http://localhost:8080/th_czg/dynamicThymeleaf


Whitelabel Error Page
This application has no configured error view, so you are seeing this as a fallback.
Sun Mar 31 23:30:21 CST 2019
There was an unexpected error (type=Internal Server Error, status=500).
Failed to invoke handler method with resolved arguments: [0][type=org.springframework.validation.support.BindingAwareConcurrentModel][value={}] on public java.lang.String com.younghare.springBoothelloworld.controller.ThymeleafController.dynamicThymeleaf(org.springframework.ui.ModelMap)
網(wǎng)絡(luò)解決方案--好像也沒辦法解決----有哪位大神幫我留言一下
http://javaetmoi.com/2017/12/migration-spring-web-mvc-vers-spring-webflux/
【spring boot學(xué)習(xí)】Model&ModelMap&ModelAndView--csdn
在pom.xml中引入SpringMVC的支持,就解決了
<!--添加springmvc的支持 public String test(ModelMap map)//需要SpringMVC的依賴庫(kù)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
thymeleaf常用標(biāo)簽的使用方法
thymeleaf的簡(jiǎn)單用法-常用標(biāo)簽-csdm
- 基本使用方式
- 對(duì)象引用方式
- 時(shí)間類型轉(zhuǎn)換
- text 與utext
- URL
- 引入靜態(tài)資源文件js/css
- 條件判斷 th:if 或th:unless
- 循環(huán)th:each
- th:swith與th:case
thymeleaf綜合例子test.html,來自github
#測(cè)試路徑
http://localhost:8080/th_czg/test
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head lang="en">
<meta charset="UTF-8" />
<title></title>
<!-- <script th:src="@{/static/js/test.js}"></script> -->
</head>
<body>
<div>
用戶姓名:<input th:id="${user.name}" th:name="${user.name}" th:value="${user.name}"/>
<br/>
用戶年齡:<input th:value="${user.age}"/>
<br/>
用戶生日:<input th:value="${user.birthday}"/>
<br/>
用戶生日:<input th:value="${#dates.format(user.birthday, 'yyyy-MM-dd')}"/>
<br/>
</div>
<br/>
<div th:object="${user}">
用戶姓名:<input th:id="*{name}" th:name="*{name}" th:value="*{name}"/>
<br/>
用戶年齡:<input th:value="*{age}"/>
<br/>
用戶生日:<input th:value="*{#dates.format(birthday, 'yyyy-MM-dd hh:mm:ss')}"/>
<br/>
</div>
<br/>
text 與 utext :<br/>
<span th:text="${user.desc}">abc</span>
<br/>
<span th:utext="${user.desc}">abc</span>
<br/>
<br/>
URL:<br/>
<a href="" th:href="@{http://www.imooc.com}">網(wǎng)站地址</a>
<br/>
<br/>
<form th:action="@{/th/postform}" th:object="${user}" method="post" th:method="post">
<input type="text" th:field="*{name}"/>
<input type="text" th:field="*{age}"/>
<input type="submit"/>
</form>
<br/>
<br/>
<div th:if="${user.age} == 18">十八歲的天空</div>
<div th:if="${user.age} gt 18">你老了</div>
<div th:if="${user.age} lt 18">你很年輕</div>
<div th:if="${user.age} ge 18">大于等于</div>
<div th:if="${user.age} le 18">小于等于</div>
<br/>
<br/>
<select>
<option >選擇框</option>
<option th:selected="${user.name eq 'lee'}">lee</option>
<option th:selected="${user.name eq 'imooc'}">imooc</option>
<option th:selected="${user.name eq 'LeeCX'}">LeeCX</option>
</select>
<br/>
<br/>
<table>
<tr>
<th>姓名</th>
<th>年齡</th>
<th>年齡備注</th>
<th>生日</th>
</tr>
<tr th:each="person:${userList}">
<td th:text="${person.name}"></td>
<td th:text="${person.age}"></td>
<td th:text="${person.age gt 18} ? 你老了 : 你很年輕">18歲</td>
<td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd hh:mm:ss')}"></td>
</tr>
</table>
<br/>
<br/>
<div th:switch="${user.name}">
<p th:case="'lee'">lee</p>
<p th:case="#{roles.manager}">普通管理員</p>
<p th:case="#{roles.superadmin}">超級(jí)管理員</p>
<p th:case="*">其他用戶</p>
</div>
<br/>
</body>
</html>
Springboot異常處理
Springboot配置全局的異常捕獲--web頁(yè)面跳轉(zhuǎn)
頁(yè)面跳轉(zhuǎn)形式
ajax形式
統(tǒng)一返回異常的形式
創(chuàng)建模擬異常的ErrorController.java
@Controller
@RequestMapping("err")
public class ErrorController {
@RequestMapping("/error")
public String error() {
int a = 1 / 0; //除零錯(cuò)誤
return "thymeleaf/error";//不存在的地址
}
@RequestMapping("/ajaxerror")
public String ajaxerror() {
return "thymeleaf/ajaxerror";
}
@RequestMapping("/getAjaxerror")
@ResponseBody
public IYounghareJSONResult getAjaxerror() {
int a = 1 / 0;
return IYounghareJSONResult.ok();
}
}
#故意除零異常
http://localhost:8080/err/error
springMVC出現(xiàn)Cannot resolve symbol 'HttpServletRequest
在pom.xml中引入SpringMVC的支持
<!--添加springmvc的支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
訪問網(wǎng)頁(yè)http://localhost:8080//err/error 發(fā)現(xiàn)錯(cuò)誤如下圖

編寫我們自己的異常處理類IYounghareExceptionHandler.java
注意注解部分
@ControllerAdvice //spring mvc提供了ControllerAdvice注解對(duì)異常進(jìn)行統(tǒng)一的處理,拿到這些異常信息后,可以做一些處理,比如提供一個(gè)統(tǒng)一的web界
public class IYounghareExceptionHandler {
public static final String YOUNGHARE_ERROR_VIEW = "thymeleaf/error";
@ExceptionHandler(value = Exception.class)
public Object errorHandler(HttpServletRequest reqest,
HttpServletResponse response, Exception e) throws Exception {
e.printStackTrace();
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", reqest.getRequestURL()); //發(fā)生錯(cuò)誤的地址
mav.setViewName(YOUNGHARE_ERROR_VIEW); //設(shè)置錯(cuò)誤頁(yè)面
return mav;
}
}
編寫自己的error.html提示頁(yè)面
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head lang="en">
<meta charset="UTF-8" />
<title>捕獲全局異常</title>
</head>
<body>
攔截到了我們捕獲的異常,我們可以根據(jù)項(xiàng)目需要美化該頁(yè)面
<h1 style="color: red">發(fā)生錯(cuò)誤:</h1>
<div th:text="${url}"></div>
<div th:text="${exception.message}"></div>
</body>
</html>
Spring Boot 系列(八)@ControllerAdvice 攔截異常并統(tǒng)一處理

SpringBoot配置全局的異常捕獲 - ajax形式
測(cè)試地址:
http://localhost:8080//err/ajaxerror
在application.properties文件中為SpringMVC 設(shè)置static地址
#Spring Boot的默認(rèn)靜態(tài)資源的路徑為:===主要是js的文件如ajaxerror.js
#spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
#優(yōu)先級(jí)從從高到低。
spring.mvc.static-path-pattern=/static/**

到這里先把工程做個(gè)備份
https://yunpan.#/surl_yLKZ52FG45K (提取碼:1a6e)
統(tǒng)一異常處理
定義自己的異常處理類
用@ControllerAdvice+@ExceptionHandler(ServiceException.class) //要捕獲的異常類