29.Spring Boot中异常处理与REST格式处理

我在项目中是想作纯粹的先后端分离的,全部数据都经过接口来返回,那么在这个过程势必须要解决两个问题,一是对异常的处理还有一个就是当出现404这样的错误的时候我也须要把这个异常封装成json的格式给到前端,我在网上找的一个博客见连接在项目中使用SpringMVC全局异常处理,这篇文章其实已经能很好的处理一些自定义的异常与系统出现的一些404等异常,可是仍是有点不大够的,主要是在返回的json格式上,当出现404的时候其实这个时候咱们也仍是想有一个data这样的字段在其中,只不过是在返回的字段中succes是false或者是为1这样的一个字段,也就是以下所示 异常数据的格式 前端

异常404的格式
正常数据的格式
返回正常数据的格式
那么在前一篇文章中那样我感受仍是不大够的须要进行补充一下

1.修改ErrorDTO

把原博客中的ErrorDTO修改为JsonDTO须要作的就是在JsonDTO中增长一个success跟data属性,那么在每一个接口中我返回数据的时候我就返回这个JsonDTO回去java

package com.gz.whblog.utils;

public class JsonDTO {
    
    private boolean success;
    private int msgcode;
    private String msg;
    private Object data;

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public int getMsgcode() {
        return msgcode;
    }

    public void setMsgcode(int msgcode) {
        this.msgcode = msgcode;
    }

    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;
    }

    public JsonDTO(){

    }

    public JsonDTO(boolean success,int msgcode,String msg,Object data){
        super();
        this.success = success;
        this.msgcode = msgcode;
        this.msg = msg;
        this.data = data;
    }

}
复制代码

请注意这里的data是使用object来修饰的,我无论你增删改查返回的数据是ArrayList仍是字典仍是什么东西我都能给你存git

2.CustomRestExceptionHandler的改写

package com.gz.whblog.utils;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.util.ArrayList;

/**
* @description: 用来监听处理全局异常
*
* @return: 
**/

@ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler {

//    处理自定义异常
    @ExceptionHandler(CustomException.class)
    public ResponseEntity<Object> handleCustomerException(CustomException ex){
        final JsonDTO customeJsonDTD = new JsonDTO(false,ex.getMsgCode(),ex.getLocalizedMessage(),new ArrayList<>());
        return new ResponseEntity<Object>(customeJsonDTD,new HttpHeaders(),ex.getHttpStatus());
    }

//    处理通用异常,这里举例说明如何覆盖处理 请求方法不支持的异类
    @Override
    protected  ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        final JsonDTO customeJsonDTD = new JsonDTO(false,status.value(),"httpRequestMethodNotSupported",new ArrayList<>());
        System.out.println("我是全局处理请求方法不支持方法");
        return new ResponseEntity<Object>(customeJsonDTD,new HttpHeaders(),status);
    }

//    重写系统的404方法
    @Override
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        final JsonDTO customeJsonDTD = new JsonDTO(false,status.value(),"NoHandlerFoundException",new ArrayList<>());
        System.out.println("我是全局处理404异常方法");
        return new ResponseEntity<Object>(customeJsonDTD,new HttpHeaders(),status);
    }
}
复制代码

在自定义异常的方法中,若是遇到异常在data部分返回data部分就是一个空的list,固然这里返回的data也能够你去写null,可是我认为在这个地方写一个返回的空数组更好github

  • 1.是你在调用自定义异常的时候也能够不要去管这个data部分的值了;
  • 2.是前端拿到这个data值不要去处理为null的一些异常问题 另外在这个地方,须要注意的是这里对系统出现的异常代码像,我才重写了404跟405两个问题,若是你要处理500的问题,那你是须要再次重写的,你可能会说这我怎么知道要重写多少方法?不要紧这是很容易找到的 点击ResponseEntityExceptionHandler进去查看源码
    这里就是一些异常类
    如下就是能够重写的一些方法
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(
			HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		pageNotFoundLogger.warn(ex.getMessage());

		Set<HttpMethod> supportedMethods = ex.getSupportedHttpMethods();
		if (!CollectionUtils.isEmpty(supportedMethods)) {
			headers.setAllow(supportedMethods);
		}
		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(
			HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		List<MediaType> mediaTypes = ex.getSupportedMediaTypes();
		if (!CollectionUtils.isEmpty(mediaTypes)) {
			headers.setAccept(mediaTypes);
		}

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleHttpMediaTypeNotAcceptable(
			HttpMediaTypeNotAcceptableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}

	protected ResponseEntity<Object> handleMissingPathVariable(
			MissingPathVariableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleMissingServletRequestParameter(
			MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleServletRequestBindingException(
			ServletRequestBindingException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleConversionNotSupported(
			ConversionNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleTypeMismatch(
			TypeMismatchException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleHttpMessageNotReadable(
			HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleHttpMessageNotWritable(
			HttpMessageNotWritableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleMethodArgumentNotValid(
			MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleMissingServletRequestPart(
			MissingServletRequestPartException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleBindException(
			BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
protected ResponseEntity<Object> handleNoHandlerFoundException(
			NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

		return handleExceptionInternal(ex, null, headers, status, request);
	}
复制代码
@Nullable
	protected ResponseEntity<Object> handleAsyncRequestTimeoutException(
			AsyncRequestTimeoutException ex, HttpHeaders headers, HttpStatus status, WebRequest webRequest) {

		if (webRequest instanceof ServletWebRequest) {
			ServletWebRequest servletWebRequest = (ServletWebRequest) webRequest;
			HttpServletResponse response = servletWebRequest.getResponse();
			if (response != null && response.isCommitted()) {
				if (logger.isWarnEnabled()) {
					logger.warn("Async request timed out");
				}
				return null;
			}
		}

		return handleExceptionInternal(ex, null, headers, status, webRequest);
	}
复制代码
protected ResponseEntity<Object> handleExceptionInternal(
			Exception ex, @Nullable Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {

		if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
			request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
		}
		return new ResponseEntity<>(body, headers, status);
	}
复制代码

至于以为过多嫌麻烦的话,我也不知作别人高手是怎么处理的,我目前的一些方法就是挨个这样重写了web

3.自定义异常CustomException

package com.gz.whblog.utils;

import org.springframework.http.HttpStatus;

/**
* @description: 自定义异常类
*
* @return: 
**/
public class CustomException extends RuntimeException {

    private HttpStatus httpStatus;

    private int msgCode;
    public CustomException(HttpStatus httpStatus,int msgCode,String message){
        super(message);
        this.httpStatus = httpStatus;
        this.msgCode = msgCode;
    }

    public CustomException(String message,int errorCode,Exception e){
        super(message,e.getCause());
    }

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }

    public void setHttpStatus(HttpStatus httpStatus) {
        this.httpStatus = httpStatus;
    }

    public int getMsgCode() {
        return msgCode;
    }

    public void setMsgCode(int msgCode) {
        this.msgCode = msgCode;
    }
    
}
复制代码

4.异常状态码枚举类ExceptionEnum

package com.gz.whblog.utils;

import org.springframework.http.HttpStatus;

/**
* @description: 异常枚举类
*
* @return: 
**/
public enum  ExceptionEnum {

//    跟数据库CRUD有关的一些自定义代码
    ADD_DATA_SUCCESS(20000,"操做成功",HttpStatus.OK),
    QUERARY_DATA_SUCCESS(20001,"查询成功",HttpStatus.OK),
    INSERT_DATA_SUCCESS(20002,"插入成功",HttpStatus.OK),
    UPDATE_DATA_SUCCESS(20003,"更新数据成功",HttpStatus.OK),
    DELETE_DATA_SUCCESS(20004,"删除数据成功",HttpStatus.OK),

//    用户登陆有关的一些自定义代码
    LOGIN_USER_SUCCESS(10000,"登陆成功",HttpStatus.OK),
    LOGIN_USERNAME_ERROR(10001,"用户名错误",HttpStatus.BAD_REQUEST),
    LOGIN_PASSWORD_ERROR(10002,"登陆密码错误",HttpStatus.BAD_REQUEST),
    LOGIN_VERIFICODE_ERROR(10003,"验证码错误",HttpStatus.BAD_REQUEST),
    LOGIN_TELEPHONE_ERROR(10004,"手机号错误",HttpStatus.BAD_REQUEST),

    ;

    private int msgcode;
    private String msgdesc;
    private HttpStatus httpStatus;


    ExceptionEnum(int msgcode, String msgdesc, HttpStatus status) {
        this.msgcode = msgcode;
        this.msgdesc = msgdesc;
        this.httpStatus = status;
    }

    public int getMsgcode() {
        return msgcode;
    }

    public void setMsgcode(int msgcode) {
        this.msgcode = msgcode;
    }

    public String getMsgdesc() {
        return msgdesc;
    }

    public void setMsgdesc(String msgdesc) {
        this.msgdesc = msgdesc;
    }

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }

    public void setHttpStatus(HttpStatus httpStatus) {
        this.httpStatus = httpStatus;
    }
}
复制代码

若是有其余的一些操做还能够继续添加一些状态码的 Github同步更新我的学习笔记,若是这篇文章对你有好处点个星星你不亏 WiHongNoteBookspring

相关文章
相关标签/搜索