本文主要是介绍个人博客开发之blog-api项目统一结果集api封装,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
由于返回json api
格式接口,所以我们需要通过java bean封装一个统一数据返回格式,便于和前端约定交互,
状态码枚举ResultCode
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
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;}}
响应结果方法工具类
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
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
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";@Overridepublic 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
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的业务* 是否请求包含了包装注解 标记,没有直接返回不需要重写返回体,*/@Overridepublic 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 处理响应的具体业务方法*/@Overridepublic 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格式返回
关注公众号猿小叔获取更多干货分享
这篇关于个人博客开发之blog-api项目统一结果集api封装的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!