概述
实际业务开发中,由于多种业务情况,返回值不统一,对于对接方或前端数据对接时数据格式不统一,
处理起来比较麻烦,对系统的所有返回数据进行统一封装,保持一致
以及特殊定制类返回值不需要统一格式,另外定义注解是否使用统一返回形式:NotGlobalRet
直接定义自动封装返回对象对了切面类
全局请求前置切面
@Aspect
@Component
@Slf4j
public class SysLogAspect {
private Long startTime;
private Long endTime;
public SysLogAspect() {
}
@Pointcut("execution(public * com.project.controller..*.*(..)) ")
public void webLogPointcut() {
}
@Before("webLogPointcut()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
return;
}
HttpServletRequest request = attributes.getRequest();
String sessionId = request.getHeader(SecurityConstant.TOKEN);
String from = request.getHeader(SecurityConstant.FROM);
startTime = System.currentTimeMillis();
log.info("请求sessionId : 【{}】,请求来源:{},请求url:{},请求ip : {}",
from, sessionId, request.getServletPath(), WebUtil.getIP(request));
log.info("请求参数 : {}", Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(returning = "ret", pointcut = "webLogPointcut()")
public void doAfterReturning(Object ret) throws Throwable {
endTime = System.currentTimeMillis();
log.info("请求耗时:{}", (endTime - startTime));
}
返回对象处理类
@Slf4j
@RestControllerAdvice
@ConditionalOnProperty(prefix="filter", name = "enabled", havingValue = "true")
public class RetAutoConfiguration implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
Method method = returnType.getMethod();
if (method == null) {
return false;
}
Class<? extends Method> clazz = method.getClass();
boolean notGlobalRetFlag = returnType.hasMethodAnnotation(NotGlobalRet.class);
if (clazz.isAnnotationPresent(NotGlobalRet.class) || notGlobalRetFlag) {
return false;
}
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
if (body instanceof RetObj || body instanceof Exception) {
return body;
}
return RetObj.success(body);
}
}
配置中的值
filter.enabled=true
不使用统一封装格式注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface NotGlobalRet {
}
统一返回格式类
@NoArgsConstructor
@Data
public class RetObj<T> implements Serializable {
private static final long serialVersionUID = 1L;
private int flag;
private String msg;
private T obj;
private RetObj(IRetCode retCode) {
this(retCode, null, retCode.getMsg());
}
private RetObj(IRetCode retCode, String msg) {
this(retCode, null, msg);
}
private RetObj(IRetCode retCode, T data) {
this(retCode, data, retCode.getMsg());
}
private RetObj(IRetCode retCode, T data, String msg) {
this(retCode.getCode(), data, msg);
}
private RetObj(int flag, T obj, String msg) {
this.flag = flag;
this.obj = obj;
this.msg = msg;
}
public static <T> RetObj<T> success() {
return new RetObj<>(CommonRetEnum.SUCCESS);
}
public static <T> RetObj<T> success(T obj) {
return new RetObj<>(CommonRetEnum.SUCCESS, obj);
}
public static <T> RetObj<T> success(IRetCode retCode, String msg) {
return new RetObj<>(retCode, msg);
}
public static <T> RetObj<T> fail(String msg) {
return new RetObj<>(CommonRetEnum.FAIL, msg);
}
public static <T> RetObj<T> fail(int flag, String msg) {
return new RetObj<>(flag, null, msg);
}
public static <T> RetObj<T> fail(int flag, String msg, T obj) {
return new RetObj<>(flag, obj, msg);
}
public static <T> RetObj<T> fail(IRetCode resultCode) {
return new RetObj<>(resultCode);
}
public static <T> RetObj<T> fail(IRetCode resultCode, String msg) {
return new RetObj<>(resultCode, msg);
}
public static <T> RetObj<T> fail(T obj) {
return new RetObj<>(CommonRetEnum.FAIL, obj);
}
}
业务api接口
public interface IRetCode extends Serializable {
int getCode();
String getMsg();
}
业务代码枚举
public enum CommonRetEnum implements IRetCode {
SUCCESS(1, "成功"),
OLD_SUCCESS(0, "成功"),
FAIL(-1, "失败"),
EXCEPTION(5001, "系统繁忙"),
UN_AUTHENTICATION(4010, "请求未认证");
final int code;
final String msg;
@Override
public int getCode() {
return this.code;
}
@Override
public String getMsg() {
return this.msg;
}
private CommonRetEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
}