SpringBoot实战:SpringBoot之Rest Full接口自定义返回数据类型(ResponseBodyAdvice)

故事扮演 提交于 2020-03-01 23:42:42

我们在日常开发的过程中,经常会要求统一返回数据格式。如要求统一访问格式为

{
  "success": 请求是否成功,
  "message": 请求消息,
  "data": 请求数据
}

那我们要如何实现呢,接下来将演示接口自定义返回数据类型

一般接口返回的数据格式的都是json,故现在pom.xml引入fastjson包

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

先建一个符合统一数据格式的实体类

import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;

/**
 * @author wusy
 * Company: xxxxxx科技有限公司
 * Createtime : 2020/2/28 22:11
 * Description : rest full 统一返回包装类
 */
@Setter
@Getter
public class ResultObjectModel<T> implements Serializable {
    /**
     * 返回是否成功
     */
    private Boolean success;

    /**
     * 提示信息
     */
    private String message;

    /**
     * 返回数据内容
     */
    private T data;

    public ResultObjectModel() {
    }

    public ResultObjectModel(Boolean success, String message, T data) {
        this.success = success;
        this.message = message;
        this.data = data;
    }

    /**
     * 返回成功
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ResultObjectModel success(T data){
        return new ResultObjectModel(true , "请求成功" , data);
    }

    /**
     * 返回成功
     * @param message
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ResultObjectModel success(String message ,T data){
        return new ResultObjectModel(true , message , data);
    }

    /**
     * 失败
     * @param message
     * @return
     */
    public static ResultObjectModel fail(String message){
        return new ResultObjectModel(true , message , null);
    }

    /**
     * 失败
     * @param message
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ResultObjectModel fail(String message ,T data){
        return new ResultObjectModel(false , message , data);
    }
}

然后修改Rest Full接口类

import com.alibaba.fastjson.JSONObject;
import com.wusy.demo.model.ResultObjectModel;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author wusy
 * Company: xxxxxx科技有限公司
 * Createtime : 2020/2/24 21:54
 * Description :
 */
@RestController
@RequestMapping("/api/demo")
public class HelloWorldController {


    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public ResultObjectModel hello() {
        JSONObject json = new JSONObject();
        json.put("name", "wusy");
        json.put("company" , "xxxxxx科技有限公司");
        return ResultObjectModel.success(json);
    }
}

运行应用,打开浏览器,在地址栏输入http://127.0.0.1:8787/api/demo/hello,观察结果

到这里我们实现了单个接口的数据统一返回,但是一般一个应用的接口都非常多,如果每一个接口都修改过去这显然是不合理的,伟大的Spring怎么会没有考虑到这些呢,SpringBoot提供了ResponseBodyAdvice供我们自定义返回数据格式。

import com.wusy.demo.model.ResultObjectModel;
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.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @author wusy
 * Company: xxxxxx科技有限公司
 * Createtime : 2020/2/28 22:04
 * Description : rest full 全局统一返回封装
 */
@RestControllerAdvice
public class GlobalControllerAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 判断哪些需要拦截
     * @param returnType
     * @param converterType
     * @return
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }


    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        //如果返回的数据是ResultObjectModel、Byte、String类型则不进行封装
        if( body instanceof ResultObjectModel || body instanceof Byte || body instanceof String) {
            return body;
        }
        return this.getWrapperResponse(request , body);
    }

    /**
     * 返回正常的信息
     * @param request
     * @param data
     * @return
     */
    private ResultObjectModel<Object> getWrapperResponse(ServerHttpRequest request, Object data) {

        return new ResultObjectModel<>(true, "请求成功" , data);
    }
}

修改rest full接口类

import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author wusy
 * Company: xxxxxx科技有限公司
 * Createtime : 2020/2/24 21:54
 * Description :
 */
@RestController
@RequestMapping("/api/demo")
public class HelloWorldController {


    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public JSONObject hello() {
        JSONObject json = new JSONObject();
        json.put("name", "wusy");
        json.put("company" , "xxxxxx科技有限公司");
        return json;
    }
}

运行应用,打开浏览器,在地址栏输入http://127.0.0.1:8787/api/demo/hello,观察结果

通过对比前后请求结果可知,Rest Full接口自定义返回数据类型演示结束。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!