文章目录
如题
从事开发的小伙伴想必都知道,当一个项目逐渐庞大时,特别是前后端分离的项目,我们与前端交互时,往往需要将所有数据交互的返回结果都按统一的格式封装,这样制定一个标准,看起来简单,整洁,便于理解,以便于我们跟前端小姐姐深入交流~
这里我记录一下自己用到的结果封装类,有需要的可以参考,拿走不谢。
1. 自定义全局响应类
package com.xxx.common.response;
import lombok.Data;
@Data
public class ResponseBean<T> {
/**
* 200:操作成功 -1:操作失败
**/
// http 状态码
private boolean success;
// 返回的数据
private T data;
public static <T> ResponseBean<T> success(T data) {
ResponseBean<T> responseBean = new ResponseBean<>();
responseBean.setSuccess(true);
responseBean.setData(data);
return responseBean;
}
public static <T> ResponseBean<T> error(T errorData) {
ResponseBean<T> responseBean = new ResponseBean<>();
responseBean.setSuccess(false);
responseBean.setData(errorData);
return responseBean;
}
public static <T> ResponseBean<T> success() {
ResponseBean<T> responseBean = new ResponseBean<>();
responseBean.setSuccess(true);
return responseBean;
}
}
代码很简单,就不做介绍了。
那么产生异常的错误码如何定义呢?看下面,首先自定义一个BaseError错误的父接口,后面所有枚举的错误类都要实现该接口:
2. 自定义error基础接口(父接口):
package com.xxx.common.error;
/**
* 自定义的错误描述枚举类需实现该接口
**/
public interface BaseError {
/**
* 获取错误码
*
* @return
*/
int getErrorCode();
/**
* 获取错误信息
*
* @return
*/
String getErrorMsg();
/**
* 设置错误信息
*
* @param message
* @return
*/
BaseError setErrorMsg(String message);
}
2.1 基于业务的错误码类和异常类封装:
- BusinessCodeEnum(业务错误码枚举类封装):
package com.xxx.common.error;
import lombok.Getter;
/**
* 业务错误码:返回结果的状态码
* 如果想要代码更具维护性一点,可以定义不同种类的错误码,都实现 BaseCodeInterface
**/
@Getter
public enum BusinessCodeEnum implements BaseError {
// ——注:括号内参数为(errcode: "", errorMsg: "")
//假设,通用的异常以0000开头
PARAMETER_ERROR(00001, "参数不合法"),
// 数据操作错误自定义
BODY_NOT_MATCH(400, "请求的数据格式不符!"),
SIGNATURE_NOT_MATCH(401, "请求的数字签名不匹配!"),
NOT_FOUND(404, "未找到该资源!"),
INTERNAL_SERVER_ERROR(500, "服务器内部错误!"),
SERVER_BUSY(503, "服务器正忙,请稍后再试!"),
//用户相关自定义:10000**
USER_ACCOUNT_NOT_FOUND(10001, "账号不存在!"),
DoNotAllowToDisableTheCurrentUser(10002, "不允许禁用当前用户"),
//业务异常自定义
// ...
/**
* 错误码
*/
private int errorCode;
/**
* 错误描述
*/
private String errorMsg;
BusinessCodeEnum(int errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
@Override
public int getErrorCode() {
return this.errorCode;
}
@Override
public String getErrorMsg() {
return this.errorMsg;
}
@Override
public BaseError setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
return this;
}
}
- BusinessException(业务异常类封装):
package com.xxx.common.error;
import lombok.Data;
/**
* 业务异常
*
* @Author channy
* @Date 2020/3/1 14:47
* @Version 1.0
**/
@Data
public class BusinessException extends Exception implements BaseError {
//所有实现了BaseError的ErrorEnum.
private BaseError baseError;
//直接构造错误消息的构造异常
public BusinessException(BaseError baseError) {
super(baseError.getErrorMsg());
this.baseError = baseError;
}
//自定义错误消息的构造异常
public BusinessException(BaseError baseError, String customErrorMessage) {
super();
this.baseError = baseError;
this.baseError.setErrorMsg(customErrorMessage);
}
@Override
public int getErrorCode() {
return this.baseError.getErrorCode();
}
@Override
public String getErrorMsg() {
return this.baseError.getErrorMsg();
}
@Override
public BaseError setErrorMsg(String message) {
this.baseError.setErrorMsg(message);
return this;
}
}
2.2 基于系统的错误码类和异常封装:
- SystemCodeEnum(系统错误码类自定义):
package com.xxx.common.error;
public enum SystemCodeEnum implements BaseError {
PARAMETER_ERROR(50000, "参数不合法"),
TOKEN_ERROR(50001, "用户未认证");
/**
* 错误码
*/
private int errorCode;
/**
* 错误描述
*/
private String errorMsg;
SystemCodeEnum(int errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
@Override
public int getErrorCode() {
return this.errorCode;
}
@Override
public String getErrorMsg() {
return this.errorMsg;
}
@Override
public BaseError setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
return this;
}
}
- SystemException(系统异常类封装):
package com.xxx.common.error;
// 继承异常基类,实现自定义错误父接口
public class SystemException extends Exception implements BaseError {
//所有实现了BaseError的ErrorEnum.
private BaseError baseError;
//直接构造错误消息的构造异常
public SystemException(BaseError baseError) {
super(baseError.getErrorMsg());
this.baseError = baseError;
}
//自定义错误消息的构造异常
public SystemException(BaseError baseError, String customErrorMessage) {
super(customErrorMessage);
this.baseError = baseError;
this.baseError.setErrorMsg(customErrorMessage);
}
@Override
public int getErrorCode() {
return this.baseError.getErrorCode();
}
@Override
public String getErrorMsg() {
return this.baseError.getErrorMsg();
}
@Override
public BaseError setErrorMsg(String message) {
this.baseError.setErrorMsg(message);
return this;
}
}
3. 自定义MyMebMvcConfigurer配置类实现WebMvcConfigurer接口
package com.xxx.config;
import com.xxx.common.error.BusinessException;
import com.xxx.common.error.SystemException;
import com.xxx.common.response.ResponseBean;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
/**
* @Author cyl
* @Date 2020/12/13 13:48
* @Version 1.0
**/
@Configuration
public class MyMebMvcConfigurer implements WebMvcConfigurer {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
resolvers.add((httpServletRequest, httpServletResponse, o, e) -> {
ResponseBean result;
HashMap<String, Object> errorData = new HashMap<>();
logger.info("请求错误,url:{}", httpServletRequest.getRequestURL());
if (e instanceof BusinessException) {
BusinessException businessException = (BusinessException) e;
logger.info("业务模块-错误码:{},错误信息:{}", businessException.getErrorCode(), businessException.getErrorMsg());
errorData.put("errorCode", businessException.getErrorCode());
errorData.put("errorMsg", businessException.getErrorMsg());
} else if (e instanceof SystemException) {
SystemException systemException = (SystemException) e;
logger.info("系统模块-错误码:{},错误信息:{}", systemException.getErrorCode(), systemException.getErrorMsg());
errorData.put("errorCode", systemException.getErrorCode());
errorData.put("errorMsg", systemException.getErrorMsg());
} else if (e instanceof UnauthorizedException) {
UnauthorizedException unauthorizedException = (UnauthorizedException) e;
logger.info("系统模块-错误码:{},错误信息:{}", HttpStatus.UNAUTHORIZED.value(), unauthorizedException.getMessage());
errorData.put("errorCode", HttpStatus.UNAUTHORIZED.value());
errorData.put("errorMsg", "服务器向你抛了一个异常,并表示(操作无权限)");
} else if (e instanceof HttpRequestMethodNotSupportedException) {
logger.info("系统模块-错误码:{},错误信息:{}", HttpStatus.BAD_REQUEST.value(), e.getMessage());
errorData.put("errorCode", HttpStatus.BAD_REQUEST.value());
errorData.put("errorMsg", "不支持该http请求方式");
} else if (e instanceof NoHandlerFoundException) {
logger.error("接口不存在-错误码:{},错误信息:{}", HttpStatus.NOT_FOUND.value(), e.getMessage());
errorData.put("errorCode", HttpStatus.NOT_FOUND.value());
errorData.put("errorMsg", "API接口:[" + httpServletRequest.getServletPath() + "]不存在");
} else {
logger.error("系统异常-错误码:{},错误信息:{}", HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage(), e);
errorData.put("errorCode", HttpStatus.INTERNAL_SERVER_ERROR.value());
errorData.put("errorMsg", "服务器异常,请联系管理员");
}
result = ResponseBean.error(errorData);
responseResult(httpServletResponse, result);
return new ModelAndView();
});
}
/**
* <h2>响应结果</h2>
*
* @param response
* @param result
*/
private void responseResult(HttpServletResponse response, ResponseBean result) {
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-type", "application/json;charset=UTF-8");
response.setStatus(HttpStatus.OK.value());
try {
ObjectMapper objectMapper = new ObjectMapper();
response.getWriter().write(objectMapper.writeValueAsString(result));
} catch (IOException ex) {
logger.error(ex.getMessage());
}
}
}
最后举例子调用以上封装类
- controller层(调用的是以全局结果封装类作为返回的格式):
@GetMapping("/detail/{id}")
public ResponseBean detail(@PathVariable String id) throws BusinessException {
Xxx detail = xxxService.detail(id);
return ResponseBean.success(detail);
}
// 删除
@GetMapping("/delete/{id}")
public ResponseBean delete(@PathVariable String id) throws BusinessException {
xxxService.delete(id);
return ResponseBean.success();
}
- service层(重点看对异常的抛出怎么调用以上自定义的异常类):
// 业务级
@Override
public Xxx detail(String id) throws BusinessException {
XxxVO xxxVO = new XxxVO();
logger.info("detail id:" + id);
Xxx xxx = xxxMapper.selectByPrimaryKey(id);
if(xxx==null){
throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"订单不存在");
}
BeanUtils.copyProperties(xxx,xxxVO);
return xxxVO; // 返回订单信息
}
// 系统级
/**
* 删除用户
* @param id 用户ID
*/
@Transactional
@Override
public void deleteById(Long id) throws SystemException {
User user = userMapper.selectByPrimaryKey(id);
ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
if(user==null){
throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"要删除的用户不存在");
}
if(user.getId().equals(activeUser.getUser().getId())){
throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"不能删除当前登入用户");
}
userMapper.deleteByPrimaryKey(id);
//删除对应[用户-角色]记录
Example o = new Example(UserRole.class);
o.createCriteria().andEqualTo("userId",id);
userRoleMapper.deleteByExample(o);
}
// ...
以JSON格式显示返回的结果集是这样的形式:
{
“success”: true,
“data”: “xxxxxxx”
}
{
“success”: false,
“data”: {
“errorCode”: 1,
“errorMsg”: “xxxxxxxxx”
}
}
以上就是这些。
共勉~
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/157273.html