首页 > 其他分享 >还在使用ResponseEntity?试试自己构建一个优雅的响应返回类和通用分页结果类

还在使用ResponseEntity?试试自己构建一个优雅的响应返回类和通用分页结果类

时间:2023-09-20 21:36:52浏览次数:36  
标签:code return 分页 Response ResponseEntity message 优雅 data public

直接上代码

1. 通用响应实体类

import java.util.Objects;

/**
 * <p> 响应实体类 </p>
 *
 * @author lishaohui
 * @since 2023/9/20 19:58
 */
public class Response<T> {

    /**
     * 返回结果状态码
     */
    private Integer code;

    /**
     * 返回结果状态信息
     */
    private String message;

    /**
     * 返回主体数据
     */
    private T data;

    protected Response() {

    }

    protected Response(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * 构造通用成功返回{@link Result Response}工厂方法
     *
     * @return {@link Result Response}
     */
    public static <T> Response<T> ok() {
        return Response.ok(null);
    }

    /**
     * 构造通用成功返回{@link Response Response}工厂方法
     *
     * @return {@link Response Response}
     */
    public static <T> Response<T> ok(T data) {
        return Response.of(BaseResponseStatus.SUCCESS_CODE, BaseResponseStatus.SUCCESS_MESSAGE, data);
    }

    /**
     * 构造通用失败返回{@link Result Response}工厂方法
     *
     * @return {@link Result Response}
     */
    public static <T> Response<T> error() {
        return Response.error(null);
    }

    /**
     * 构造通用失败返回{@link Result Result}工厂方法
     *
     * @param message 返回消息
     * @return {@link Result Result}
     */
    public static <T> Response<T> error(String message) {
        return Response.of(BaseResponseStatus.ERROR_CODE, message);
    }

    /**
     * 构造通用失败返回{@link Result Result}工厂方法
     *
     * @param code    返回状态码
     * @param message 返回消息
     * @return {@link Result Result}
     */
    public static <T> Response<T> error(Integer code, String message) {
        return Response.of(code, message);
    }

    /**
     * 构造{@link Response Response}工厂方法
     *
     * @param code    自定义返回码
     * @param message 自定义返回消息
     * @return {@link Response Response}
     */
    public static <T> Response<T> of(Integer code, String message) {
        return Response.<T>builder()
                .code(code)
                .message(message)
                .data(null)
                .build();
    }

    /**
     * 构造{@link Response Response}工厂方法
     *
     * @param code    自定义返回码
     * @param message 自定义返回消息
     * @param data    返回数据
     * @return {@link Response Response}
     */
    public static <T> Response<T> of(int code, String message, T data) {
        return Response.<T>builder()
                .code(code)
                .message(message)
                .data(data)
                .build();
    }

    /**
     * 构造{@link Response Response}工厂方法
     *
     * @param status 自定义返回格式
     * @param data   返回数据
     * @return {@link Response Response}
     */
    public static <T> Response<T> of(BaseResponseStatus status, T data) {
        return Response.<T>builder()
                .code(status.getCode())
                .message(status.getMessage())
                .data(data)
                .build();
    }

    public Response(Builder<T> tBuilder) {
        this.code = tBuilder.code;
        this.message = tBuilder.message;
        this.data = tBuilder.data;
    }

    public static <T> Builder<T> builder() {
        return new Builder<>();
    }

    public static <T> Builder<T> builder(Response<T> response) {
        Builder<T> builder = new Builder<>();
        builder.code = response.code;
        builder.message = response.message;
        builder.data = response.data;
        return builder;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Response<?> response = (Response<?>) o;
        return Objects.equals(getCode(), response.getCode())
                && Objects.equals(getMessage(), response.getMessage())
                && Objects.equals(getData(), response.getData());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getCode(), getMessage(), getData());
    }

    @Override
    public String toString() {
        return "Response{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }

    public static class Builder<T> {
        private Integer code;
        private String message;
        private T data;

        private Builder() {
        }

        public Builder<T> code(Integer code) {
            this.code = code;
            return this;
        }

        public Builder<T> message(String message) {
            this.message = message;
            return this;
        }

        public Builder<T> data(T data) {
            this.data = data;
            return this;
        }

        public Response<T> build() {
            return new Response<>(this);
        }

    }

    /**
     * Base响应状态接口
     */
    public interface BaseResponseStatus {

        int SUCCESS_CODE = 200;
        int ERROR_CODE = 500;

        String SUCCESS_MESSAGE = "成功";
        String ERROR_MESSAGE = "失败";

        /**
         * 获取状态码
         */
        Integer getCode();

        /**
         * 获取返回信息
         */
        String getMessage();

    }

    public enum ResponseStatus implements BaseResponseStatus {

        /**
         * 200 成功 使用约定的成功状态码
         */
        SUCCESS(BaseResponseStatus.SUCCESS_CODE, BaseResponseStatus.SUCCESS_MESSAGE),

        /**
         * 500 异常 使用约定的失败状态码
         */
        ERROR(BaseResponseStatus.ERROR_CODE, BaseResponseStatus.ERROR_MESSAGE),

        /**
         * 参数错误
         */
        ILLEGAL_ARGUMENT(400, "参数错误"),

        UNAUTHORIZED(401, "未认证"),

        FORBIDDEN(403, "未授权"),

        WRONG_PASSWORD(411, "账号或密码错误"),

        ACCOUNT_DISABLED(412, "账号已被禁用"),
        ;

        ResponseStatus(Integer code, String msg) {
            this.code = code;
            this.message = msg;
        }

        @Override
        public Integer getCode() {
            return code;
        }

        @Override
        public String getMessage() {
            return message;
        }

        /**
         * 返回状态码,{@link ResponseStatus#SUCCESS_CODE SUCCESS(200)}表示成功
         */
        private final Integer code;

        /**
         * 返回描述信息
         */
        private final String message;
    }
}

2. 响应结果测试

    public Response<String> stringResponse() {
        return Response.<String>builder()
                .code(201)
                .message("test message")
                .data("test data")
                .build();
    }

3.通用分页

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * <p>通用分页返回</p>
 *
 * @author lishaohui
 * @since 2023/9/20 21:06
 */
public class Page<T> implements Serializable {

    /**
     * 总条数
     */
    private long count;

    /**
     * 当前页数据
     */
    private List<T> rows;

    private Page() {

    }

    private Page(long count, List<T> rows) {
        this.count = count;
        this.rows = rows;
    }

    public Page(Builder<T> builder) {
        this.count = builder.count;
        this.rows = builder.rows;
    }

    public static <T> Page<T> fill(long count, List<T> rows) {
        return Page.<T>builder()
                .count(count)
                .rows(rows)
                .build();
    }

    public static <T> Page<T> empty(){
        return Page.fill(0, new ArrayList<>());
    }

    public static <T> Builder<T> builder(Page<T> page) {
        Builder<T> builder = new Builder<>();
        builder.count = page.count;
        builder.rows = page.rows;
        return builder;
    }

    public static <T> Builder<T> builder() {
        return new Builder<>();
    }

    public long getCount() {
        return count;
    }

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

    public List<T> getRows() {
        return rows;
    }

    public void setRows(List<T> rows) {
        this.rows = rows;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Page<?> page = (Page<?>) o;
        return getCount() == page.getCount() && Objects.equals(getRows(), page.getRows());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getCount(), getRows());
    }

    @Override
    public String toString() {
        return "Page{" +
                "count=" + count +
                ", rows=" + rows +
                '}';
    }

    public static class Builder<T> {
        private long count;
        private List<T> rows;

        private Builder() {
        }

        public Builder<T> count(long count) {
            this.count = count;
            return this;
        }

        public Builder<T> rows(List<T> rows) {
            this.rows = rows;
            return this;
        }

        public Page<T> build() {
            return new Page<>(this);
        }
    }
}

标签:code,return,分页,Response,ResponseEntity,message,优雅,data,public
From: https://www.cnblogs.com/lsh-admin/p/17718420.html

相关文章

  • 关于pagehelper分页无法使用的情况下进行分页,以及对显示页码navigatePages限制
    IntegerpageNum=1;IntegerpageSize=10;//计算总数inttotal=list==null?0:list.size();//计算总页数intpageSum=total%pageSize==0?total/pageSize:total/pageSize+1;PageHelper.startPage(pageNum,pageSize);//开始分页List<ActTrsDetailDto>collect......
  • 从 5s 到 0.5s!CompletableFuture 异步任务优化技巧,确实优雅!
    一个接口可能需要调用N个其他服务的接口,这在项目开发中还是挺常见的。举个例子:用户请求获取订单信息,可能需要调用用户信息、商品详情、物流信息、商品推荐等接口,最后再汇总数据统一返回。如果是串行(按顺序依次执行每个任务)执行的话,接口的响应速度会非常慢。考虑到这些接口之间......
  • mysql大数据量 分页查询优化
    最近我老表问我一个面试问题,如果数据量很大,分页查询怎么优化。个人觉得无非就是sql优化,那无非就是走索引,避免回表查询(覆盖索引,也就是不要用select *  ,走主键索引,叶子节点有保存了数据),减少回表查询次数(定位到非聚簇索引树的叶子节点少,小表驱动大表等)我下面自己测了一个500......
  • linux系统 分页指令
    ......
  • DRF之分页类源码分析
    【一】分页类介绍DjangoRESTframework(DRF)是一个用于构建WebAPI的强大工具,它提供了分页功能,使你能够控制API响应的数据量。在DRF中,分页功能由分页类(PaginatorClass)来管理。【二】内置分页类在DRF中,分页类通常位于rest_framework.pagination模块中,它们用于分割长列表或......
  • Java游戏服务器之优雅停服
    一、写随笔的原因:最近项目开发中,停服的时候发现停服的时候,日志无法打印,看了下原因,是因为项目使用了SpringBoot中的logback,无法控制日志关闭在项目内部停服逻辑之前关闭。研究之后,整理下关于优雅停服的相关处理二、具体的内容:1.什么是优雅停服让应用程序处理完正在运行的逻辑,......
  • Mybatis Plus 分页查询数据
    MybatisPlus分页查询数据一、分页配置packagecom.example.demomybatispage.config;importcom.baomidou.mybatisplus.annotation.DbType;importcom.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;importcom.baomidou.mybatisplus.extension.plugins.......
  • JS装饰器模式,让你的代码更优雅
    装饰器模式JavaScript装饰器模式是一种常用的设计模式,它可以让你在不改变原有代码的情况下,动态地给对象添加新的功能。本文将通过一个实际的例子来介绍JavaScript装饰器模式的使用方法和优势。装饰器模式的定义装饰器模式是一种结构型设计模式,它允许你在运行时动态地给一个对象......
  • 系统内存管理:虚拟内存、内存分段与分页、页表缓存TLB以及Linux内存管理
    虚拟内存虚拟内存是一种操作系统提供的机制,用于将每个进程分配的独立的虚拟地址空间映射到实际的物理内存地址空间上。通过使用虚拟内存,操作系统可以有效地解决多个应用程序直接操作物理内存可能引发的冲突问题。在使用虚拟内存的情况下,每个进程都有自己的独立的虚拟地址空间,它们......
  • SQL Server 2012分页获取数据的同时获取到总记录数(优化)
    ALTERPROCEDUREdbo.tpGetPageRecords(@OffSetRowNoINT,@FetchRowNoINT,@TotalCountINTOUT)ASSELECTCSTNO,CSTABBRFROMDBATABCWHERECSTABBRLIKE'A%'ORDERBYCSTNOOFFSET(@OffSetRowNo-1)*@FetchRowNoROWSFETCH......