服務器端如何優雅的統一返回值和統一接收值?

1、在做服務器端開發的時候,我們經常要返回特定格式的數據給調用方,通常有狀態碼、消息和數據,如何將這些返回結果統一起來呢?請看下面…

public class ResponseVO<T>  extends  PageVO  {
    private ResultCode status;
    private String msg;
    private T data;

    public ResponseVO(ResultCode status, T data, String msg) {
        this.status = status;
        this.data = data;
        this.msg = msg;
    }

    public ResponseVO(ResultCode status, T data) {
        this.status = status;
        this.data = data;
    }

    public ResponseVO(ResultCode status, String msg) {
        this.status = status;
        this.msg = msg;
    }

    public ResponseVO() {
    }

    public ResultCode getStatus() {
        return this.status;
    }

    public void setStatus(ResultCode status) {
        this.status = status;
    }

    public String getMsg() {
        return this.msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return this.data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String toString() {
        return "ResponseVO{status=" + this.status + ", msg='" + this.msg + '\'' + ", data=" + this.data + '}';
    }
}

狀態碼這裏用的是個枚舉值,數據用的是泛型代替,爲了兼容返回各種類型的數據

public enum ResultCode {
    SUCCESS(1),
    FAIL(2);

    private int status;

    private ResultCode(int status) {
        this.status = status;
    }

    public int getStatus() {
        return this.status;
    }

    public void setStatus(int status) {
        this.status = status;
    }
}

如果是分頁查接口呢?我們不僅需要返回數據,還要返回分頁信息,通常有:總頁數(totalPage)
、總數據量(totalItem)、當前頁(currentPage),那我們可以定義一個PageVO類,
ResponseVO繼承PageVO,如下面:

public class PageVO {
    private Integer totalPage;
    private Integer totalItem;
    private Integer currentPage;

    public PageVO() {
    }

    public Integer getTotalPage() {
        return this.totalPage;
    }

    public void setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
    }

    public Integer getTotalItem() {
        return this.totalItem;
    }

    public void setTotalItem(Integer totalItem) {
        this.totalItem = totalItem;
    }

    public Integer getCurrentPage() {
        return this.currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public String toString() {
        return "PageVO{totalPage=" + this.totalPage + ", totalItem=" + this.totalItem + ", currentPage=" + this.currentPage + '}';
    }
}

光說不練假把戲,奉上使用用例:這是個分頁查詢,這裏返回的是個ResponseVO對象,@ResponseBody實現,或者在Controller類上加@RestController全局統一返回對象,我這用的是 @RestController,該返回對象包含4個基本信息:總頁數、總數據量、狀態碼、數據

	@RequestMapping("/queryList")
    public ResponseVO<List<ApiVO>> queryList(@RequestBody ApiDTO request){
        PageResponseVO<List<ApiVO>> responseVO = new PageResponseVO<>();
        responseVO.setStatus(ResultCode.SUCCESS);
        int totalCount = apiService.queryTotalCount(request.getKey());
        responseVO.setTotalItem(totalCount);
        responseVO.setTotalPage(PageUtil.getTotalPage(totalCount,request));
        if(totalCount==0){
            responseVO.setData(Collections.emptyList());
            return responseVO;
        }
        List<Api> list = apiService.queryList(request.getStartNum(),request.getCount(),request.getKey());
        List<Long> userIds = list.stream().map(Api :: getLastUpdateUserId).collect(Collectors.toList());
        Map<Long, User> userMap = userService.queryUserMap(userIds);
        List<ApiVO> data = ApiConverter.toApiVO(list,userMap);
        responseVO.setData(data);
        return responseVO;
    }
    

PageUtil

public class PageUtil {
    public PageUtil() {
    }

    public static int getTotalPage(int count, PageCondition pageCondition) {
        return count % pageCondition.getCount().intValue() == 0 ? count / pageCondition.getCount().intValue() : count / pageCondition.getCount().intValue() + 1;
    }
}

稍微說參數統一接收,例如我這裏使用的ApiDTO,這個key就是頁碼傳來的查詢參數,如果有其他類型參數往ApiDTO加就是了,不同業務場景下有不同的DTO,PageCondition這個類是處理分頁信息的,前端通常會傳pageNum和count這兩個參數,我們需要根據這兩個參數計算分頁的偏移量startNum(我用的是mysql的limit分頁:limit startNum,count,數據量不大就不做分頁性能優化了emmmmm…)

public class ApiDTO extends PageCondition {
    private String key;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
public class PageCondition {
    public static final Integer PAGE_NUM_DEFAULT = Integer.valueOf(1);
    public static final Integer PAGE_SIZE_DEFAULT = Integer.valueOf(20);
    private Integer pageNum;
    private Integer count;

    public PageCondition() {
    }

    public Integer getPageNum() {
        return this.pageNum;
    }

    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }

    public Integer getCount() {
        return this.count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public Integer getStartNum() {
        if (this.pageNum != null && this.pageNum.intValue() != 0) {
            if (this.count != null && this.count.intValue() != 0) {
                return (this.pageNum.intValue() - 1) * this.count.intValue();
            } else {
                throw new BusinessException("No pageSize.");
            }
        } else {
            throw new BusinessException("No pageNum.");
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章