如题
从事开发的小伙伴想必都知道,当一个项目逐渐庞大时,特别是前后端分离的项目,我们与前端交互时,往往需要将所有数据交互的返回结果都按统一的格式封装,这样制定一个标准,看起来简单,整洁,便于理解,以便于我们跟前端小姐姐深入交流~ 这里我记录一下自己用到的结果封装类,有需要的可以参考,拿走不谢。
1. 自定义全局响应类
package com.xxx.common.response;
import lombok.Data;
@Data
public class ResponseBean<T> {
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 {
int getErrorCode();
String getErrorMsg();
BaseError setErrorMsg(String message);
}
2.1 基于业务的错误码类和异常类封装:
- BusinessCodeEnum(业务错误码枚举类封装):
package com.xxx.common.error;
import lombok.Getter;
@Getter
public enum BusinessCodeEnum implements BaseError {
PARAMETER_ERROR(00001, "参数不合法"),
BODY_NOT_MATCH(400, "请求的数据格式不符!"),
SIGNATURE_NOT_MATCH(401, "请求的数字签名不匹配!"),
NOT_FOUND(404, "未找到该资源!"),
INTERNAL_SERVER_ERROR(500, "服务器内部错误!"),
SERVER_BUSY(503, "服务器正忙,请稍后再试!"),
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;
@Data
public class BusinessException extends Exception implements BaseError {
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 {
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;
@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();
});
}
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;
}
@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” } }
以上就是这些。
共勉~
|