1.創(chuàng)建基于spring boot+jpa的基本的增刪
請(qǐng)參考spring boot+jpa簡(jiǎn)單實(shí)現(xiàn)就不多介紹了醋界。本次主要是統(tǒng)一異常處理的演進(jìn)過程,還有一個(gè)目的是剛看的異常處理視頻蹭睡,記錄一下,方便以后查看尼酿。
2.最原始的返回(不友好恭理,不利于前端處理)
@RequestMapping("findByIdFirst")
public Student findByIdFirst(@RequestParam String id) {
return studentService.findById(id).orElse(null);
}
@RequestMapping("findAllFirst")
public List<Student> findByIdFirst() {
return studentService.list();
}
-
如果存在Student的id為
d4c-2cfaa59e-27a8-46c1-8578-da715e44b214
則返回。
-
如果查詢的id不存在剿牺,則什么都不返回
-
如果存在數(shù)據(jù)企垦,list接口返回
如果不存在數(shù)據(jù),則返回晒来。
如果用這種接口返回?cái)?shù)據(jù)钞诡,肯定會(huì)被前端捶爆。(還是不要嘗試了!哎荧降!說多了都是淚=芋铩!朵诫!)
3 .怎么改進(jìn)
我們定義一個(gè)ResultInfo對(duì)象來統(tǒng)一定義返回結(jié)果辛友。
package com.d4c.exception.demo.pojo;
import lombok.Data;
/**
* Created with IntelliJ IDEA.
* User: liangqing.zhao(zlq)
* Date: 2019/10/7 19:41
* Description:
*/
@Data
public class ResultInfo<T> {
/**
*返回碼
*/
private Integer code;
/**
*返回提示信息
*/
private String msg;
/**
*返回具體對(duì)象
*/
private T data;
}
上面的接口就可以改進(jìn)為
@RequestMapping("findByIdSecond")
public ResultInfo findByIdSecond(@RequestParam String id) {
Student stu = studentService.findById(id).orElse(null);
ResultInfo resultInfo = new ResultInfo();
resultInfo.setCode(1);
resultInfo.setMsg("成功!");
resultInfo.setData(stu);
return resultInfo;
}
@RequestMapping("findAllSecond")
public ResultInfo findByIdSecond() {
List<Student> listStudent = studentService.list();
ResultInfo resultInfo = new ResultInfo();
resultInfo.setCode(1);
resultInfo.setMsg("成功剪返!");
resultInfo.setData(listStudent);
return resultInfo;
}
-
改造后的數(shù)據(jù)(1條數(shù)據(jù))
-
list
現(xiàn)在不管有沒有數(shù)據(jù)废累,共同的部分code和msg都會(huì)返回,這樣更有利于前端的判斷處理數(shù)據(jù)随夸。
但是九默,每次返回成功都要寫一遍
ResultInfo resultInfo = new ResultInfo();
resultInfo.setCode(1);
resultInfo.setMsg("成功!");
這有點(diǎn)太繁瑣宾毒,一點(diǎn)都不優(yōu)雅M招蕖!诈铛!
4. 代碼共同的部分提取成一個(gè)工具類乙各。
package com.d4c.exception.demo.utils;
import com.d4c.exception.demo.pojo.ResultInfo;
/**
* Created with IntelliJ IDEA.
* User: liangqing.zhao(zlq)
* Date: 2019/10/7 19:42
* Description:
*/
public class ResultInfoOldUtil {
public static ResultInfo success(Object object) {
ResultInfo result = new ResultInfo();
result.setCode(1);
result.setMsg("成功!");
result.setData(object);
return result;
}
}
然后幢竹,代碼就能改成
@RequestMapping("findByIdThird")
public ResultInfo findByIdThird(@RequestParam String id) {
Student stu = studentService.findById(id).orElse(null);
return ResultInfoOldUtil.success(stu);
}
@RequestMapping("findAllThird")
public ResultInfo findByIdThird() {
List<Student> listStudent = studentService.list();
return ResultInfoOldUtil.success(listStudent);
}
效果與上面一樣耳峦。
到上面我們就處理了我們成功的代碼,但只是成功焕毫,前提是代碼不出現(xiàn)異常蹲坷,但是這也許有可能吧!R仂循签!
我們來主動(dòng)測(cè)試一個(gè)異常看看
@RequestMapping("findByIdFourth")
public ResultInfo findByIdFourth(@RequestParam String id) {
Student stu = studentService.findById(id).orElse(null);
Integer count = 1/0;
return ResultInfoOldUtil.success(stu);
}
直接異常拋到頁面上疙咸,這怎么可以县匠。
因此又處理了一下,變成了
@RequestMapping("findByIdFourth")
public ResultInfo findByIdFourth(@RequestParam String id) {
try {
Student stu = studentService.findById(id).orElse(null);
Integer count = 1/0;
return ResultInfoOldUtil.success(stu);
} catch (Exception e) {
e.printStackTrace();
return ResultInfoOldUtil.error();
}
}
@RequestMapping("findAllFourth")
public ResultInfo findByIdFourth() throws Exception {
try {
List<Student> listStudent = studentService.list();
throw new Exception("出現(xiàn)異常");
} catch (Exception e) {
e.printStackTrace();
return ResultInfoOldUtil.error();
}
}
此時(shí)的結(jié)果變成了
異常也變得優(yōu)雅了撒轮!
但是乞旦,如果異常多了,我們分別處理题山,就有變成了兰粉。
try {...} catch(...) {...}catch(...).... finally {...}
這樣處理如此繁瑣。能不能把這些異常統(tǒng)一處理一下顶瞳,處理一次亲桦,下次就不有再處理同樣的異常了崖蜜。
5.統(tǒng)一異常處理@ControllerAdvice+ @ExceptionHandler(...)
package com.d4c.exception.demo.handle;
import com.d4c.exception.demo.enums.ResultInfoEnum;
import com.d4c.exception.demo.exception.StudentException;
import com.d4c.exception.demo.pojo.ResultInfo;
import com.d4c.exception.demo.utils.ResultInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Created with IntelliJ IDEA.
* User: liangqing.zhao(zlq)
* Date: 2019/10/7 19:40
* Description:
*/
@ControllerAdvice
@Slf4j
public class ExceptionHandle {
@ExceptionHandler(Exception.class)
@ResponseBody
public ResultInfo handleException(Exception e) {
if (e instanceof StudentException) {
StudentException studentException = (StudentException) e;
return ResultInfoUtil.error(studentException.getCode(), studentException.getMessage());
} else if (e instanceof NullPointerException) {
ResultInfoEnum resultInfoEnum = ResultInfoEnum.NULL_POINT_EXCEPTION;
return ResultInfoUtil.error(resultInfoEnum.getCode(), resultInfoEnum.getMsg());
} else if (e instanceof IndexOutOfBoundsException) {
ResultInfoEnum resultInfoEnum = ResultInfoEnum.INDEX_OUT_BOUNDS_EXCEPTION;
return ResultInfoUtil.error(resultInfoEnum.getCode(), resultInfoEnum.getMsg());
} else {
log.error("【系統(tǒng)異常】{}", e);
ResultInfoEnum unknown = ResultInfoEnum.UNKNOWN;
return ResultInfoUtil.error(unknown.getCode(), unknown.getMsg());
}
}
}
package com.d4c.exception.demo.exception;
import com.d4c.exception.demo.enums.ResultInfoEnum;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import net.bytebuddy.implementation.bind.annotation.Super;
/**
* Created with IntelliJ IDEA.
* User: liangqing.zhao(zlq)
* Date: 2019/10/7 19:36
* Description:
*/
@Getter
@Setter
public class StudentException extends RuntimeException {
private Integer code;
public StudentException(ResultInfoEnum resultInfoEnum){
super(resultInfoEnum.getMsg());
this.code = resultInfoEnum.getCode();
}
}
然后我們就不用顯示的try catch了客峭。只要在ExceptionHandle處理一遍就好了。就變成了下面:
@RequestMapping("findByIdFifth")
public ResultInfo findByIdFifth(@RequestParam String id) {
Student stu = studentService.findById(id).orElse(null);
Integer count = 1 / 0;
return ResultInfoOldUtil.success(stu);
}
@RequestMapping("findAllFifth")
public ResultInfo findByIdFifth() throws Exception {
List<Student> listStudent = studentService.list();
throw new Exception("出現(xiàn)異常");
}
6.自定義異常類StudentException
package com.d4c.exception.demo.exception;
import com.d4c.exception.demo.enums.ResultInfoEnum;
import lombok.Getter;
import lombok.Setter;
/**
* Created with IntelliJ IDEA.
* User: liangqing.zhao(zlq)
* Date: 2019/10/7 19:36
* Description:
*/
@Getter
@Setter
public class StudentException extends RuntimeException {
private Integer code;
public StudentException(ResultInfoEnum resultInfoEnum) {
super(resultInfoEnum.getMsg());
this.code = resultInfoEnum.getCode();
}
}
7.統(tǒng)一管理異常信息ResultInfoEnum
package com.d4c.exception.demo.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Created with IntelliJ IDEA.
* User: liangqing.zhao(zlq)
* Date: 2019/10/7 19:39
* Description:
* @author
*/
@Getter
@AllArgsConstructor
public enum ResultInfoEnum {
/**
* 成功
*/
SUCCESS(1,"success"),
/**
* 失敗
*/
FAILED(2,"failed"),
/**
*未知錯(cuò)誤
*/
UNKNOWN(3,"未知錯(cuò)誤"),
/**
*id不存在
*/
NOT_EXIST_ID(4,"要查詢的id不存在"),
NULL_POINT_EXCEPTION(5,"空指針異常"),
INDEX_OUT_BOUNDS_EXCEPTION(6,"下標(biāo)超出異常")
;
private Integer code;
private String msg;
}
8.優(yōu)化后的ResultInfoUtil
package com.d4c.exception.demo.utils;
import com.d4c.exception.demo.enums.ResultInfoEnum;
import com.d4c.exception.demo.pojo.ResultInfo;
/**
* Created with IntelliJ IDEA.
* User: liangqing.zhao(zlq)
* Date: 2019/10/7 19:42
* Description:
*/
public class ResultInfoUtil {
public static ResultInfo success(Object object) {
ResultInfo result = new ResultInfo();
ResultInfoEnum successEnum = ResultInfoEnum.SUCCESS;
result.setCode(successEnum.getCode());
result.setMsg(successEnum.getMsg());
result.setData(object);
return result;
}
public static ResultInfo success() {
return success(null);
}
public static ResultInfo error(Integer code ,String msg) {
ResultInfo result = new ResultInfo();
result.setCode(code);
result.setMsg(msg);
return result;
}
}
最后抡柿,代碼優(yōu)化成
json與統(tǒng)一異常處理到這里就告一段落了舔琅。
具體的源碼請(qǐng)參考exception-demo