个人博客开发之blog-api项目统一结果集api封装 前言

前言

由于返回json api 格式接口,所以我们需要通过java bean封装一个统一数据返回格式,便于和前端约定交互,

状态码枚举ResultCode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
java复制代码package cn.soboys.core.ret;


import lombok.Getter;

/**
* @author kenx
* @version 1.0
* @date 2021/6/17 15:35
* 响应码枚举,对应HTTP状态码
*/
@Getter
public enum ResultCode {

SUCCESS(200, "成功"),//成功
//FAIL(400, "失败"),//失败
BAD_REQUEST(400, "Bad Request"),
UNAUTHORIZED(401, "认证失败"),//未认证
NOT_FOUND(404, "接口不存在"),//接口不存在
INTERNAL_SERVER_ERROR(500, "系统繁忙"),//服务器内部错误
METHOD_NOT_ALLOWED(405,"方法不被允许"),

/*参数错误:1001-1999*/
PARAMS_IS_INVALID(1001, "参数无效"),
PARAMS_IS_BLANK(1002, "参数为空");
/*用户错误2001-2999*/


private Integer code;
private String message;

ResultCode(int code, String message) {
this.code = code;
this.message = message;
}
}

结果体Result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
java复制代码package cn.soboys.core.ret;

import lombok.Data;

import java.io.Serializable;

/**
* @author kenx
* @version 1.0
* @date 2021/6/17 15:47
* 统一API响应结果格式封装
*/
@Data
public class Result<T> implements Serializable {

private static final long serialVersionUID = 6308315887056661996L;
private Integer code;
private String message;
private T data;


public Result setResult(ResultCode resultCode) {
this.code = resultCode.getCode();
this.message = resultCode.getMessage();
return this;
}

public Result setResult(ResultCode resultCode, T data) {
this.code = resultCode.getCode();
this.message = resultCode.getMessage();
this.setData(data);
return this;
}


}

响应结果方法工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
java复制代码package cn.soboys.core.ret;

/**
* @author kenx
* @version 1.0
* @date 2021/6/17 16:30
* 响应结果返回封装
*/
public class ResultResponse {
private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";

// 只返回状态
public static Result success() {
return new Result()
.setResult(ResultCode.SUCCESS);
}

// 成功返回数据
public static Result success(Object data) {
return new Result()
.setResult(ResultCode.SUCCESS, data);


}

// 失败
public static Result failure(ResultCode resultCode) {
return new Result()
.setResult(resultCode);
}

// 失败
public static Result failure(ResultCode resultCode, Object data) {
return new Result()
.setResult(resultCode, data);
}



}

自定义解析controller拦截

注解@ResponseResult

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码package cn.soboys.core.ret;

import java.lang.annotation.*;

/**
* @author kenx
* @version 1.0
* @date 2021/6/17 16:43
* 统一包装接口返回的值 Result
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseResult {
}

请求拦截ResponseResultInterceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
java复制代码package cn.soboys.core.ret;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
* @author kenx
* @version 1.0
* @date 2021/6/17 17:10
* 请求拦截
*/
public class ResponseResultInterceptor implements HandlerInterceptor {

//标记名称
public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//请求方法
if (handler instanceof HandlerMethod) {
final HandlerMethod handlerMethod = (HandlerMethod) handler;
final Class<?> clazz = handlerMethod.getBeanType();
final Method method = handlerMethod.getMethod();
//判断是否在对象上加了注解
if (clazz.isAnnotationPresent(ResponseResult.class)) {
//设置此请求返回体需要包装,往下传递,在ResponseBodyAdvice接口进行判断
request.setAttribute(RESPONSE_RESULT_ANN, clazz.getAnnotation(ResponseResult.class));
//方法体上是否有注解
} else if (method.isAnnotationPresent(ResponseResult.class)) {
//设置此请求返回体需要包装,往下传递,在ResponseBodyAdvice接口进行判断
request.setAttribute(RESPONSE_RESULT_ANN, clazz.getAnnotation(ResponseResult.class));
}
}
return true;
}
}

请求全局解析ResponseResultHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
java复制代码package cn.soboys.core.ret;

import cn.soboys.core.utils.HttpContextUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;

/**
* @author kenx
* @version 1.0
* @date 2021/6/17 16:47
* 全局统一响应返回体处理
*/
@Slf4j
@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {

public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";

/**
* @param methodParameter
* @param aClass
* @return 此处如果返回false , 则不执行当前Advice的业务
* 是否请求包含了包装注解 标记,没有直接返回不需要重写返回体,
*/
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
HttpServletRequest request = HttpContextUtil.getRequest();
//判断请求是否有包装标志
ResponseResult responseResultAnn = (ResponseResult) request.getAttribute(RESPONSE_RESULT_ANN);
return responseResultAnn == null ? false : true;
}

/**
* @param body
* @param methodParameter
* @param mediaType
* @param aClass
* @param serverHttpRequest
* @param serverHttpResponse
* @return 处理响应的具体业务方法
*/
@Override
public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
if (body instanceof Result) {
return body;
} else if (body instanceof String) {
return JSON.toJSONString(ResultResponse.success(body));
} else {
return ResultResponse.success(body);
}
}
}

具体详细内容请参考我这篇章 Spring Boot 无侵入式 实现RESTful API接口统一JSON格式返回

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%