
初始化异常
@GetMapping("/test1")
public String test1() {
// TODO 这里只是模拟异常,假设业务处理的时候出现错误了,或者空指针了等等...
int i = 10 / 0;
return "test1";
}
打开浏览器访问时

采用try catch 方法 手动抓取异常;这是很多人想到得,但是明显得弊端时;出现大量的重复的try catch;代码量上去了;
@GetMapping("/test2")
public Map<String, String> test2() {
Map<String, String> result = new HashMap<>(16);
// TODO 直接捕获所有代码块,然后在 cache
try {
int i = 10 / 0;
result.put("code", "200");
result.put("data", "具体返回的结果集");
} catch (Exception e) {
result.put("code", "500");
result.put("message", "请求错误");
}
return result;
}
解决方案使用全局异常捕获
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
自定义异常
package com.meyue.xiwen.exception;
/**
* 类: BaseException <br>
* 描述: 运行时异常基类<br>
*/
public class BaseException extends RuntimeException implements BaseMsgDes{
/** */
private static final long serialVersionUID = -5335258347966254381L;
private final ExceptionLevel level;
private final ExceptionCode code;
private String remark;
protected String outPusMsg;
public String getOutPusMsg() {
return outPusMsg;
}
public void setOutPusMsg(String outPusMsg) {
this.outPusMsg = outPusMsg;
}
/**
* 标题: 构造器 <br>
* 描述: TODO <br>
* @param level
* @param code
*/
public BaseException(ExceptionLevel level, ExceptionCode code) {
super();
this.level = level;
this.code = code;
}
public BaseException(String remark,String message,ExceptionLevel level, ExceptionCode code) {
super(message);
this.level = level;
this.code = code;
this.remark=remark;
}
public BaseException(Throwable cause,ExceptionLevel level, ExceptionCode code) {
super(cause);
this.level = level;
this.code = code;
}
public BaseException(String remark,String message, Throwable cause,ExceptionLevel level, ExceptionCode code) {
super(message, cause);
this.level = level;
this.code = code;
this.remark=remark;
}
public ExceptionLevel getLevel() {
return level;
}
public ExceptionCode getCode() {
return code;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
控制层输出
@RestController
public class ExceptionController {
@GetMapping("/ex")
public String ex(Integer num) {
// TODO 演示需要,实际上参数是否为空通过 @RequestParam(required = true) 就可以控制
if (num == null) {
throw new BaseException (400, "num不能为空");
}
int i = 10 / num;
return "result:" + i;
}
}
异常处理
注解概述@ControllerAdvice 捕获Controller
层抛出的异常,如果添加@ResponseBody
返回信息则为JSON
格式。@RestControllerAdvice 相当于@ControllerAdvice
与@ResponseBody
的结合体。@ExceptionHandler 统一处理一种类的异常,减少代码重复率,降低复杂度。创建一个GlobalExceptionHandler
类,并添加上@RestControllerAdvice
注解就可以定义出异常通知类了,然后在定义的方法中添加上@ExceptionHandler
即可实现异常的捕捉…
package com.meyue.xiwen.config;
import com.meyue.xiwen.bo.ErrorResponseEntity;
import com.meyue.xiwen.exception.CustomerException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName:GlobalExceptionHandler </br>
* @Description: TODO </br>
* @Author:童晶继 tongjingji01@gmail.com </br>
* @Date:
* @version:1.0
*/
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
/**
* 定义要捕获的异常 可以多个 @ExceptionHandler({})
*
* @param request request
* @param e exception
* @param response response
* @return 响应结果
*/
@ExceptionHandler(CustomerException.class)
public ErrorResponseEntity customExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
CustomerException exception = (CustomerException) e;
return new ErrorResponseEntity(exception.getCode(), exception.getMessage());
}
/**
* 捕获 RuntimeException 异常
* TODO 如果你觉得在一个 exceptionHandler 通过 if (e instanceof xxxException) 太麻烦
* TODO 那么你还可以自己写多个不同的 exceptionHandler 处理不同异常
*
* @param request request
* @param e exception
* @param response response
* @return 响应结果
*/
@ExceptionHandler(RuntimeException.class)
public ErrorResponseEntity runtimeExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
RuntimeException exception = (RuntimeException) e;
return new ErrorResponseEntity(400, exception.getMessage());
}
/**
* 通用的接口映射异常处理方
*/
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
HttpStatus status, WebRequest request) {
if (ex instanceof MethodArgumentNotValidException) {
MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
return new ResponseEntity<>(new ErrorResponseEntity(status.value(), exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
}
if (ex instanceof MethodArgumentTypeMismatchException) {
MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
logger.error("参数转换失败,方法:" + exception.getParameter().getMethod().getName() + ",参数:" + exception.getName()
+ ",信息:" + exception.getLocalizedMessage());
return new ResponseEntity<>(new ErrorResponseEntity(status.value(), "参数转换失败"), status);
}
return new ResponseEntity<>(new ErrorResponseEntity(status.value(), "参数转换失败"), status);
}
}
package com.meyue.xiwen.bo;
/**
* @ClassName:ErrorResponseEntity </br>
* @Description: TODO </br>
* @Author:童晶继 tongjingji01@gmail.com </br>
* @Date:
* @version:1.0
*/
public class ErrorResponseEntity {
private int code;
private String message;
public ErrorResponseEntity(int code, String message) {
this.code=code;
this.message=message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}