小白一枚,最近使用restful风格给前端返回数据,但有时候后台出异常了,返回的内容不是封装好的返回结果。导致前端渲染过程中出现连锁问题。搞得人头疼,而且看网上的很多人也比较繁琐,不清爽。既然自己解决了,所以在这里记录一下。希望帮到更多的小白。(我今天才知道这里居然可以上传代码段,以前写的都是截图+复制,样式太丑了)
在实际项目中,正常情况下前端拿到的数据格式为为下图:
正常格式
不想要的格式:当某段代码出异常,如果不做任何处理,返回的内容是springboot自带的返回格式。如图:
不想要的格式
那么在这种情况下,如果前端的容错不够的话,有可能会使页面“爆炸”。
所以我们想,如果代码出异常时,返回给前端的格式然后message中加入实际的错误信息,定是极好的。如图:
希望的格式
所以这篇博客的作用就是从零开始教大家如何达成上述的目的
1.首先建立统一的异常处理类CommonException,注意这里一定要继承RuntimeException
package com.exception.exception;
/**
* @author Shiyx
* @date 2019/9/4
*/
public class CommonException extends RuntimeException {
String message ;
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public CommonException(String message) {
this.message = message;
}
}
其次建立异常返回格式的CommonExceptionHandler
package com.exception.exception;
import com.exception.constant.StatusCode;
import com.exception.entity.ResponseModel;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author Shiyx
* @date 2019/9/4
*/
@ResponseBody
@ControllerAdvice
public class CommonExceptionHandler {
@ExceptionHandler
private ResponseModel commonExceptionResult(CommonException commonException){
return ResponseModel.fail(StatusCode.NOTAVAILABLE,commonException.getMessage());
}
}
以上两个文件是最主要的,当我们建立好上述的类之后,就可以来验证了
package com.exception.service.Impl;
import com.exception.exception.CommonException;
import com.exception.service.CommonService;
import org.springframework.stereotype.Service;
/**
* @author Shiyx
* @date 2019/9/4
*/
@Service
public class CommonServiceImpl implements CommonService {
/**
* 正常情况
* @return
*/
@Override
public Integer numberCurrent() {
int i = 1;
Integer j = 10;
Integer m = null;
try {
m = j / i;
} catch (Exception e) {
throw e;
}
return m;
}
/**
* 异常不处理情况
* @return
*/
@Override
public Integer number() {
int i = 0;
Integer j = 10;
Integer m = j / i;
return m;
}
/**
* 自定义异常拦截
* @return
*/
@Override
public Integer numberThrowCommonException() {
int i = 0;
Integer j = 10;
Integer m = null;
try {
m = j / i;
} catch (Exception e) {
//咱们可以再其他出异常的地方同样使用此段代码。比如:
// throw new CommonException("密码错误");
// throw new CommonException("查询条件错误");
// throw new CommonException("系统异常");
throw new CommonException("除数不能为0");
}
return m;
}
}
至此,就搞定了,然后加上其他的一些返回实体类,Controller方法等,就能够实现我最上面截图返回格式
其他的代码不知道有没有用,反正我都穿一下。
项目目录结构如下图,标准的spring的开发目录:
package com.exception.constant;
/**
* ProjectName: AlphaZ
* PackageName: com.AlphaZ.constant
* User: C0dEr
* Date: 2016-11-10
* Time: 14:51
* Description:
*/
public class StatusCode {
public static final int AVAILABLE = 0;//成功
public static final int NOTAVAILABLE = 1;//失败
}
package com.exception.controller;
import com.exception.constant.StatusCode;
import com.exception.entity.ResponseModel;
import com.exception.service.CommonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Shiyx
* @date 2019/9/4
*/
@RestController
public class CommonController {
@Autowired
private CommonService commonService;
@GetMapping("/number")
public ResponseModel number(){
Integer number = commonService.number();
return ResponseModel.sucess(StatusCode.AVAILABLE,"操作成功",number);
}
@GetMapping("/numberCurrent")
public ResponseModel numberCurrent(){
Integer number = commonService.numberCurrent();
return ResponseModel.sucess(StatusCode.AVAILABLE,"操作成功",number);
}
@GetMapping("/numberThrowCommonException")
public ResponseModel numberThrowCommonException(){
Integer number = commonService.numberThrowCommonException();
return ResponseModel.sucess(StatusCode.AVAILABLE,"操作成功",number);
}
}
package com.exception.entity;
import com.exception.constant.StatusCode;
/**
* ProjectName: YouChi
* PackageName: com.AlphaZ.entity
* User: C0dEr
* Date: 2016-11-04
* Time: 10:53
* Description:
*/
public class ResponseModel<T> {
public Integer statusCode = StatusCode.NOTAVAILABLE;
public String httpStatus = "200";
public String message;
public T data;
public ResponseModel(Integer statusCode, String httpStatus, String message, T data) {
this.statusCode = statusCode;
this.httpStatus = httpStatus;
this.message = message;
this.data = data;
}
public ResponseModel(String message, Integer statusCode, T data) {
this.statusCode = statusCode;
this.message = message;
this.data = data;
}
public ResponseModel(Integer statusCode, String message) {
this.statusCode = statusCode;
this.message = message;
this.data = null;
}
public static <T> ResponseModel fail(Integer statusCode,String message){
return new ResponseModel(statusCode,message);
}
public static <T> ResponseModel sucess(Integer statusCode,String message,T data){
return new ResponseModel(message,statusCode,data);
}
public ResponseModel() {
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Integer getStatusCode() {
return statusCode;
}
public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getHttpStatus() {
return httpStatus;
}
public void setHttpStatus(String httpStatus) {
this.httpStatus = httpStatus;
}
@Override
public String toString() {
return "ResponseModel{" +
"statusCode=" + statusCode +
", httpStatus='" + httpStatus + '\'' +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
package com.exception.service;
/**
* @author Shiyx
* @date 2019/9/4
*/
public interface CommonService {
Integer number();
Integer numberCurrent();
Integer numberThrowCommonException();
}