源码在最后
1.添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.72</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
2.自定义一个错误接口类,包含错误码和错误信息
package com.example.demo.util;
/**
* @author lyd
* @Description:
* @date 16:15
*/
public interface BaseErrorInfoInterface {
/**
* 得到错误码
*
* @return {@link String}
*/
String getResultCode();
/**
* 得到错误信息
*
* @return {@link String}
*/
String getResultMsg();
}
3.自定义一个枚举类,实现错误接口类,在这个枚举里面自定义一些错误类型
package com.example.demo.util;
/**
* 常见的枚举
*
* @author lyd
* @Description: 自定义枚举类
* @date 16:16
*/
public enum CommonEnum implements BaseErrorInfoInterface {
SUCCESS("200", "成功"),
BODY_NOT_MATCH("400", "请求的数据格式不符"),
SIGNATURE_NOT_MATCH("401", "请求的数字签名不匹配!"),
OT_FOUND("404", "未找到该资源!"),
INTERNAL_SERVER_ERROR("500", "服务器内部错误!"),
SERVER_BUSY("503", "服务器正忙,请稍后再试!");
/**
* 错误码
*/
private String resultCode;
/**
* 错误描述
*/
private String resultMsg;
CommonEnum(String resultCode, String resultMsg) {
this.resultCode = resultCode;
this.resultMsg = resultMsg;
}
@Override
public String getResultCode() {
return resultCode;
}
@Override
public String getResultMsg() {
return resultMsg;
}
}
4.自定义一个异常类,等会处理业务异常的时候用
package com.example.demo.exception;
import com.example.demo.util.BaseErrorInfoInterface;
/**
* @author lyd
* @Description: 自定义异常类
* @date 16:25
*/
public class BizException extends RuntimeException {
/**
* 错误代码
*/
private String errorCode;
/**
* 错误信息
*/
private String errorMsg;
public BizException() {
super();
}
public BizException(String message, String errorMsg) {
super(message);
this.errorMsg = errorMsg;
}
public BizException(String message, String errorCode, String errorMsg) {
super(message);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public BizException(BaseErrorInfoInterface baseErrorInfoInterface) {
super(baseErrorInfoInterface.getResultCode());
this.errorCode = baseErrorInfoInterface.getResultCode();
this.errorMsg = baseErrorInfoInterface.getResultMsg();
}
public BizException(BaseErrorInfoInterface baseErrorInfoInterface, Throwable cause) {
super(baseErrorInfoInterface.getResultCode(), cause);
this.errorCode = baseErrorInfoInterface.getResultCode();
this.errorMsg = baseErrorInfoInterface.getResultMsg();
}
public BizException(Throwable cause, String errorCode, String errorMsg) {
super(errorCode, cause);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
@Override
public synchronized Throwable fillInStackTrace() {
return super.fillInStackTrace();
}
}
5.再定义一个数据响应格式,便于数据交互
package com.example.demo.util;
import com.alibaba.fastjson.JSONObject;
/**
* @author lyd
* @Description: 自定义数据传输格式
* @date 16:40
*/
public class ResultBody {
/**
* 响应代码
*/
private String code;
/**
* 响应消息
*/
private String message;
/**
* 响应结果
*/
private Object result;
public ResultBody() {
}
public ResultBody(BaseErrorInfoInterface baseErrorInfoInterface) {
this.code = baseErrorInfoInterface.getResultCode();
this.message = baseErrorInfoInterface.getResultMsg();
}
/**
* 成功
*
* @param data 数据
* @return {@link ResultBody}
*/
public static ResultBody success(Object data) {
ResultBody resultBody = new ResultBody();
resultBody.setCode(CommonEnum.SUCCESS.getResultCode());
resultBody.setMessage(CommonEnum.SUCCESS.getResultMsg());
resultBody.setResult(data);
return resultBody;
}
/**
* 错误
*
* @param errorInfo 错误信息
* @return {@link ResultBody}
*/
public static ResultBody error(BaseErrorInfoInterface errorInfo) {
ResultBody resultBody = new ResultBody();
resultBody.setCode(errorInfo.getResultCode());
resultBody.setMessage(errorInfo.getResultMsg());
resultBody.setResult(null);
return resultBody;
}
/**
* 错误
*
* @return {@link ResultBody}
*/
public static ResultBody error(String code, String message) {
ResultBody resultBody = new ResultBody();
resultBody.setCode(code);
resultBody.setMessage(message);
resultBody.setResult(null);
return resultBody;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
6.最关键的一步:自定义一个全局异常处理类,用到两个注解@ControllerAdvice
@ExceptionHandler
package com.example.demo.exception;
import com.example.demo.util.ResultBody;
import com.example.demo.util.CommonEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* @author lyd
* @Description:自定义全局异常处理类
* @date 16:12
*/
@ControllerAdvice
public class MyExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(MyExceptionHandler.class);
/**
* 自定义的业务异常处理程序
*
* @param httpServletRequest http servlet请求
* @param ex
* @return {@link ResultBody}
*/
@ExceptionHandler(value = BizException.class)
@ResponseBody
public ResultBody bizExceptionHandler(HttpServletRequest httpServletRequest, BizException ex) {
logger.error("啦啦啦啦啦发生业务异常,原因是:" + ex.getErrorMsg());
return ResultBody.error(ex.getErrorCode(), ex.getErrorMsg());
}
/**
* 空指针异常处理程序
*
* @param req 要求的事情
* @param e e
* @return {@link ResultBody}
*/
@ExceptionHandler(value = NullPointerException.class)
@ResponseBody
public ResultBody exceptionHandler(HttpServletRequest req, NullPointerException e) {
logger.error("啦啦啦啦发生空指针异常!原因是:", e);
return ResultBody.error(CommonEnum.BODY_NOT_MATCH);
}
/**
* 其他异常处理程序
*
* @param req 要求的事情
* @param e e
* @return {@link ResultBody}
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResultBody exceptionHandler(HttpServletRequest req, Exception e) {
logger.error("啦啦啦啦发生未知异常!原因是:", e);
return ResultBody.error(CommonEnum.INTERNAL_SERVER_ERROR);
}
}
7.定义一个实体类,等会掉接口测试使用
package com.example.demo.pojo;
import java.io.Serializable;
/**
* @author lyd
* @Description:
* @date 17:19
*/
public class User implements Serializable {
private int id;
private String name;
private int age;
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;
}
}
8.controller层定义几个接口做测试
package com.example.demo.controller;
import com.example.demo.exception.BizException;
import com.example.demo.pojo.User;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
public class UserRestController {
@PostMapping("/user")
public boolean insert(User user) {
System.out.println("开始新增...");
//如果姓名为空就手动抛出一个自定义的异常!
if (user.getName() == null) {
throw new BizException("-1", "用户姓名不能为空!");
}
return true;
}
@PutMapping("/user")
public boolean update(User user) {
System.out.println("开始更新...");
//这里故意造成一个空指针的异常,并且不进行处理
String str = null;
str.equals("111");
return true;
}
@DeleteMapping("/user")
public boolean delete(User user) {
System.out.println("开始删除...");
//这里故意造成一个字符转换异常,并且不进行处理
Integer.parseInt("abc123");
System.out.println("发生异常后继续执行");
return true;
}
@GetMapping("/user")
public List<User> findByUser(User user) {
System.out.println("开始查询...");
List<User> userList = new ArrayList<>();
User user2 = new User();
user2.setId(1);
user2.setName("liuliu");
user2.setAge(18);
userList.add(user2);
return userList;
}
}
最后使用postman测试
先使用Post请求测试
可以看到有手动异常抛出
再测一下Delete请求的,看看自动的捕捉异常