目录
SpringBoot全局异常处理
springboot全局异常处理——@ControllerAdvice+ExceptionHandler
一、全局捕获异常后,返回json给浏览器
二、全局捕获异常后,返回页面给浏览器
SpringBoot全局异常处理
为了让客户端能有一个更好的体验,当客户端发送请求到服务端发生错误时服务端应该明确告诉客户端错误信息。
SpringBoot内置的异常处理返回的界面太杂乱,不够友好。我们需要将异常信息做封装处理响应给前端。本文介绍的为将错误信息统一封装成如下格式json响应给前端。
{
code:10001,
message:xxxxx,
request:GET url
}
自定义异常类
package com.lin.missyou.exception;
public class HttpException extends RuntimeException{
protected Integer code;
protected Integer httpStatusCode;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public Integer getHttpStatusCode() {
return httpStatusCode;
}
public void setHttpStatusCode(Integer httpStatusCode) {
this.httpStatusCode = httpStatusCode;
}
}
package com.lin.missyou.exception;
public class NotFoundException extends HttpException{
public NotFoundException(int code){
this.httpStatusCode = 404;
this.code = code;
}
}
package com.lin.missyou.exception;
public class ForbiddenException extends HttpException{
public ForbiddenException(int code){
this.httpStatusCode = 403;
this.code = code;
}
}
创建一个用于封装异常信息的类UnifyResponse
package com.lin.missyou.core;
public class UnifyResponse {
private int code;
private String message;
private String request;
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public String getRequest() {
return request;
}
public UnifyResponse(int code, String message, String request) {
this.code = code;
this.message = message;
this.request = request;
}
}
将异常信息写在配置文件exception-code.properties里
lin.codes[10000] = 通用异常
lin.codes[10001] = 通用参数错误
自定义配置类管理配置文件
package com.lin.missyou.core.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@PropertySource(value=”classpath:config/exception-code.properties”)
@ConfigurationProperties(prefix = “lin”)
@Component
public class ExceptionCodeConfiguration {
private Map<Integer,String> codes = new HashMap<>();
public Map<Integer, String> getCodes() {
return codes;
}
public void setCodes(Map<Integer, String> codes) {
this.codes = codes;
}
public String getMessage(int code) {
String message = codes.get(code);
return message;
}
}
创建一个全局异常处理类GlobalExceptionAdvice,用@ControllerAdvice标明异常处理类。@ResponseStatus用于指定http状态码。

@ExceptionHandler标明异常处理器,传入参数指定当前函数要处理哪种类型的异常。Springboot会帮我们把这些异常信息传入到函数。第一个函数用于处理未知异常,不需要向前端提供详细的错误原因,只需提示统一的文本信息即可。

第二个函数用于处理已知异常,需要指明具体的错误原因,需要根据Exception传递过来的信息灵活的定制httpStatusCode。ResponseEntity可以自定义很多属性,包括可以设置httpheaders,httpbodys,httpStatus。
package com.lin.missyou.core;
import com.lin.missyou.core.config.ExceptionCodeConfiguration;
import com.lin.missyou.exception.HttpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
@ControllerAdvice
public class GlobalExceptionAdvice {
@Autowired
ExceptionCodeConfiguration exceptionCodeConfiguration ;
@ExceptionHandler(Exception.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public UnifyResponse handleException(HttpServletRequest req,Exception e){
String method = req.getMethod();
String requestUrl = req.getRequestURI();
System.out.println(e);
UnifyResponse unifyResponse = new UnifyResponse(9999,”服务器错误”,method+” “+requestUrl);
return unifyResponse;
}
@ExceptionHandler(HttpException.class)
public ResponseEntity<UnifyResponse> handleHttpException(HttpServletRequest req, HttpException e){
String method = req.getMethod();
String requestUrl = req.getRequestURI();
System.out.println(e);
UnifyResponse unifyResponse = new UnifyResponse(e.getCode(),exceptionCodeConfiguration.getMessage(e.getCode()),method+” “+requestUrl);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode());
ResponseEntity<UnifyResponse> responseEntity = new ResponseEntity(unifyResponse,httpHeaders,httpStatus);
return responseEntity;
}
//参数校验
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public UnifyResponse handleBeanValidation(HttpServletRequest req, MethodArgumentNotValidException e){
String method = req.getMethod();
String requestUrl = req.getRequestURI();
List<ObjectError> errors = e.getBindingResult().getAllErrors();
String message = formatAllErrorMessages(errors);
return new UnifyResponse(10001,message,method+” “+requestUrl);
}
private String formatAllErrorMessages(List<ObjectError> errors){
StringBuffer errorMsg = new StringBuffer();
errors.forEach(error ->
errorMsg.append(error.getDefaultMessage()).append(“;”)
);
return errorMsg.toString();
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public UnifyResponse handleConstrainException(HttpServletRequest req, ConstraintViolationException e){
String method = req.getMethod();
String requestUrl = req.getRequestURI();
String message = e.getMessage();
return new UnifyResponse(10001,message,method+” “+requestUrl);
}
}
响应信息可能会出现乱码现象,修改配置文件编码。在设置面板搜索File Encodings,Default encoding for properties files选择UTF-8,勾选Transparent native-to-ascii conversion

springboot全局异常处理——@ControllerAdvice+ExceptionHandler
一、全局捕获异常后,返回json给浏览器
项目结构:

1、自定义异常类 MyException.java
package com.gui.restful;
/**

  • 自定义异常类
    */
    public class MyException extends RuntimeException{
    private String code;
    private String msg;
    public MyException(String code,String msg){
    1. this.code=code;
    2. this.msg=msg;
    }
    public String getCode() {
    1. return code;
    }
    public void setCode(String code) {
    1. this.code = code;
    }
    public String getMsg() {
    1. return msg;
    }
    public void setMsg(String msg) {
    1. this.msg = msg;
    }
    }
    2、控制器 MyController.java
    package com.gui.restful;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    /**
  • controller抛出异常
    */
    @RestController
    public class MyController {
    @RequestMapping(“hello”)
    public String hello() throws Exception{
    1. throw new MyException("101","系统异常");
    }
    }
    3、全局异常处理类 MyControllerAdvice
    package com.gui.restful;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.ResponseBody;
    import java.util.HashMap;
    import java.util.Map;
    /**
  • 全局异常捕获处理
    */
    @ControllerAdvice //controller增强器
    public class MyControllerAdvice {
    @ResponseBody
    @ExceptionHandler(value=MyException.class) //处理的异常类型
    public Map myExceptionHandler(MyException e){
    1. Map<String,String> map=new HashMap<>();
    2. map.put("code",e.getCode());
    3. map.put("msg",e.getMsg());
    4. return map;
    }
    }

更多相关文章

  1. HBase协处理器加载的三种方式
  2. 循环语句 超级全局变量 及 cURL函数
  3. 超全局变量与命名空间
  4. 从运维角度测试全局死锁以及带来的问题
  5. ORA-15040 ora-15017ASM磁盘无法挂载故障处理
  6. Java中的 9 个处理Exception的最佳实践,你知道几个?
  7. iOS Block面试题(Block的几种形式)
  8. 嵌入式ARM微处理器选型10条建议指南及核心板优势
  9. 谈谈 CSS 预处理器

随机推荐

  1. AndroidManfest
  2. Android热修复原理普及
  3. Android 4.0.3来了 优化系统
  4. [转]Android onActivityResult()不执行的
  5. Android Material Design: NavigationVie
  6. Android jni的调用过程JNI_OnLoad(),利用
  7. 修改Android自带的JAVA应用程序
  8. 【Android 开发】:Android五种布局的使用
  9. 最近在翻译国外一本新书 The Android Dev
  10. Android事务 IMMEDIATE与EXCLUSIVE模式