概述
一般情况下 controller 的返回值为了规范我们都会进行二次封装,而之前的项目里我一般都是重新去 new 一个某个返回信息的类,反正一般都是要将其写在方法中。而这个代码又不属于业务代码,所以这时候浏览学习到了 看看别人后端API接口写得,那叫一个优雅! 这样一篇文章。
得到以下思路:我们可以通过注解来表名当前的方法返回什么类型的,然后通过某个切面进行修改。
代码
首先,为了方便,将返回码和返回信息都集成在一个枚举类之中。
@AllArgsConstructor
public enum ResultCode {
SUCCESS(1,"成功"),
PARAM_IS_INVALID(1001,"参数无效"),
PARAM_IS_BLANK(1002,"参数为空"),
PARAM_TYPE_BIND_ERROR(1003,"参数类型错误"),
PARAM_NOT_COMPLETE(1004,"参数缺失"),
USER_NOT_LOGGED_IN(2001,"用户未登录或无权限"),
USER_LOGIN_ERROR(2002,"账号不存在或密码错误"),
USER_NOT_EXIST(2003,"用户不存在"),
USER_HAS_EXISTED(2004,"用户已存在");
private Integer code;
private String message;
然后再创建一个「返回类」,其中包含返回码、返回信息、具体数据,之后创建一个以上面枚举类为参数的构造函数。
@Data
public class Result implements Serializable {
private Integer code;
private String message;
private Object data;
public Result(ResultCode resultCode, Object data) {
setResultCode(resultCode);
this.data = data;
}
为了区分当前类,我们还需要编写一个注解来声明当前类需要对返回值进行封装。并且加入属性 type 进行区分信息类型。当然,上方枚举类在当前注解中使用是有歧义的,所以请忽视。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseResult {
ResultCode type() default ResultCode.SUCCESS;
}
在之后再创建一个Handler 并且将其实现 ResponseBodyAdvice<Object> 接口,以及 @ControllerAdvice 注解,实现接口的两个方法。其中在 supports() 方法之中用于判断目标对象是否包含相对应的注解,而 beforeBodyWrite() 方法就是用于封装当前数据并将其返回的方法。
@Slf4j
@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return AnnotationUtils.findAnnotation(methodParameter.getAnnotatedElement(), ResponseResult.class) != null;
}
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
ResponseResult responseResult = AnnotationUtils.findAnnotation(methodParameter.getAnnotatedElement(), ResponseResult.class);
return new Result(responseResult.type(),o).toString();
}
}
本页的评论功能已关闭