Web层统一实体规范封装

举报
S-X-S 发表于 2025/01/09 10:59:21 2025/01/09
【摘要】 1.统一响应封装 1.目录结构 2.ResultCode.java 定义http的响应状态码package com.sunxiansheng;/** * Description: 定义http的响应状态码 * @Author sun * @Create 2024/7/10 16:39 * @Version 1.0 */public class ResultCode { public ...

1.统一响应封装

1.目录结构

CleanShot 2024-07-10 at 18.28.19@2x

2.ResultCode.java 定义http的响应状态码

package com.sunxiansheng;

/**
 * Description: 定义http的响应状态码
 * @Author sun
 * @Create 2024/7/10 16:39
 * @Version 1.0
 */
public class ResultCode {

    public static final Integer SUCCESS = 200;

    public static final Integer ERROR = 500;

    public static final Integer PARAMNOTEXIST = 499;

}

3.ResultMessage.java 定义http响应的message

package com.sunxiansheng;

/**
 * Description: 定义http响应的message
 * @Author sun
 * @Create 2024/7/10 16:42
 * @Version 1.0
 */
public class ResultMessage {

    public static final String SUCCESS = "成功";

    public static final String ERROR = "失败";

}

4.Result.java 通用响应封装类

package com.sunxiansheng;

import lombok.Data;
import java.io.Serializable;

/**
 * Description: 通用响应封装类
 * @Author sun
 * @Create 2024/7/10
 * @Version 1.0
 */
@Data
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    // 是否成功
    private boolean success;

    // 响应代码
    private int code;

    // 响应消息
    private String message;

    // 响应数据
    private T data;

    // 私有构造器,防止外部直接创建
    private Result() {}

    // 使用内部建造者类进行对象构建
    public static class Builder<T> {

        private boolean success;

        private int code;

        private String message;

        private T data;

        // ============================== 链式调用设置建造者对象 ==============================
        public Builder<T> success(boolean success) {
            this.success = success;
            return this;
        }

        public Builder<T> code(int 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;
        }
        // ============================== 链式调用设置建造者对象 ==============================

        // ============================== 构建Result对象 ==============================
        public Result<T> build() {
            Result<T> result = new Result<>();
            result.success = this.success;
            result.code = this.code;
            result.message = this.message;
            result.data = this.data;
            return result;
        }
        // ============================== 构建Result对象 ==============================

    }

    // ============================== 快捷方法 ==============================
    public static <T> Result<T> ok() {
        return new Builder<T>()
                .success(true)
                .code(ResultCode.SUCCESS)
                .message(ResultMessage.SUCCESS)
                .build();
    }

    public static <T> Result<T> ok(T data) {
        return new Builder<T>()
                .success(true)
                .code(ResultCode.SUCCESS)
                .message(ResultMessage.SUCCESS)
                .data(data)
                .build();
    }

    public static <T> Result<T> ok(T data, String message) {
        return new Builder<T>()
                .success(true)
                .code(ResultCode.SUCCESS)
                .message(message)
                .data(data)
                .build();
    }

    public static <T> Result<T> fail() {
        return new Builder<T>()
                .success(false)
                .code(ResultCode.ERROR)
                .message(ResultMessage.ERROR)
                .build();
    }

    public static <T> Result<T> fail(String message) {
        return new Builder<T>()
                .success(false)
                .code(ResultCode.ERROR)
                .message(message)
                .build();
    }

    public static <T> Result<T> fail(int code, String message) {
        return new Builder<T>()
                .success(false)
                .code(code)
                .message(message)
                .build();
    }
    // ============================== 快捷方法 ==============================

}

2.统一异常处理封装(策略模式)

1.目录结构

CleanShot 2024-07-11 at 18.53.38@2x

2.response (也可以使用上面的方式,这里故意写了枚举类的方式)

1.RespBeanEnum.java 响应枚举类
package com.sunxiansheng.exception.response;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

/**
 * Description: 响应枚举类
 *
 * @Author sun
 * @Create 2024/5/5 15:15
 * @Version 1.0
 */

@Getter
@AllArgsConstructor
@ToString
public enum RespBeanEnum {
    // 通用
    SUCCESS(200, "成功"),
    ERROR(500, "失败"),
    //登录模块
    LOGIN_ERROR(500210, "用户名或者密码错误"),
    MOBILE_ERROR(500211, "手机号码格式不正确"),
    BING_ERROR(500212, "参数绑定异常"),
    MOBILE_NOT_EXIST(500213, "手机号码不存在"),
    PASSWORD_UPDATE_FAIL(500214, "更新密码失败"),

    ;
    //其他模块。。。

    // 响应码和响应信息
    private final Integer code;
    private final String message;

    /**
     * 根据响应码返回相应的枚举对象
     * @param code 响应码
     * @return 对应的枚举对象,如果没有找到则返回 null
     */
    public static RespBeanEnum getByCode(Integer code) {
        for (RespBeanEnum status : values()) {
            if (status.getCode().equals(code)) {
                return status;
            }
        }
        return null;  // 没有找到对应的code时,返回null或者可以选择抛出一个异常
    }

}
2.Result.java 通用响应封装类
package com.sunxiansheng.exception.response;

import lombok.Data;

import java.io.Serializable;

/**
 * Description: 通用响应封装类,通过枚举来获取code和message
 * @Author sun
 * @Create 2024/7/10
 * @Version 1.0
 */
@Data
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    // 是否成功
    private boolean success;

    // 响应代码
    private int code;

    // 响应消息
    private String message;

    // 响应数据
    private T data;

    // 私有构造器,防止外部直接创建
    private Result() {}

    // 使用内部建造者类进行对象构建
    public static class Builder<T> {

        private boolean success;

        private int code;

        private String message;

        private T data;

        // ============================== 链式调用设置建造者对象 ==============================
        public Builder<T> success(boolean success) {
            this.success = success;
            return this;
        }

        public Builder<T> code(int 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;
        }
        // ============================== 链式调用设置建造者对象 ==============================

        // ============================== 构建Result对象 ==============================
        public Result<T> build() {
            Result<T> result = new Result<>();
            result.success = this.success;
            result.code = this.code;
            result.message = this.message;
            result.data = this.data;
            return result;
        }
        // ============================== 构建Result对象 ==============================

    }

    // ============================== 快捷方法 ==============================
    public static <T> Result<T> ok() {
        return new Builder<T>()
                .success(true)
                .code(RespBeanEnum.SUCCESS.getCode())
                .message(RespBeanEnum.SUCCESS.getMessage())
                .build();
    }

    public static <T> Result<T> ok(T data) {
        return new Builder<T>()
                .success(true)
                .code(RespBeanEnum.SUCCESS.getCode())
                .message(RespBeanEnum.SUCCESS.getMessage())
                .data(data)
                .build();
    }

    public static <T> Result<T> ok(T data, String message) {
        return new Builder<T>()
                .success(true)
                .code(RespBeanEnum.SUCCESS.getCode())
                .message(message)
                .data(data)
                .build();
    }

    public static <T> Result<T> fail() {
        return new Builder<T>()
                .success(false)
                .code(RespBeanEnum.ERROR.getCode())
                .message(RespBeanEnum.ERROR.getMessage())
                .build();
    }

    public static <T> Result<T> fail(String message) {
        return new Builder<T>()
                .success(false)
                .code(RespBeanEnum.ERROR.getCode())
                .message(message)
                .build();
    }

    public static <T> Result<T> fail(int code, String message) {
        return new Builder<T>()
                .success(false)
                .code(code)
                .message(message)
                .build();
    }

    public static <T> Result<T> fail(RespBeanEnum respBeanEnum) {
        return new Builder<T>()
                .success(false)
                .code(respBeanEnum.getCode())
                .message(respBeanEnum.getMessage())
                .build();
    }
    // ============================== 快捷方法 ==============================

}

3.strategys 策略模式

1.ExceptionStrategy.java 策略接口核心:一个标识,一个处理逻辑的方法
package com.sunxiansheng.exception.strategys;

import com.sunxiansheng.exception.response.Result;

/**
 * Description: 处理异常的策略接口
 * @Author sun
 * @Create 2024/7/11 18:08
 * @Version 1.0
 */
public interface ExceptionStrategy {

    /**
     * 标识自己是处理什么类型异常的策略
     * @param e
     * @return
     */
    boolean supports(Exception e);

    /**
     * 具体处理异常的策略
     * @param e
     * @return
     */
    Result handleException(Exception e);

}

2.BindExceptionStrategy.java
package com.sunxiansheng.exception.strategys;
// 注意这里引入的包
import com.sunxiansheng.exception.response.RespBeanEnum;
import com.sunxiansheng.exception.response.Result;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
/**
 * Description: 参数绑定异常的策略
 * @Author sun
 * @Create 2024/7/11 18:14
 * @Version 1.0
 */
@Component
public class BindExceptionStrategy implements ExceptionStrategy {

    @Override
    public boolean supports(Exception e) {
        return e instanceof BindException;
    }

    @Override
    public Result handleException(Exception e) {
        BindException ex = (BindException) e;
        String message = "参数校验异常:" + ex.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        return Result.fail(RespBeanEnum.BING_ERROR.getCode(), message);
    }

}
3.CustomExceptionStrategy.java
package com.sunxiansheng.exception.strategys;

import com.sunxiansheng.exception.CustomException;
import com.sunxiansheng.exception.response.Result;
import org.springframework.stereotype.Component;

/**
 * Description: 自定义异常具体策略
 * @Author sun
 * @Create 2024/7/11 18:09
 * @Version 1.0
 */
@Component
public class CustomExceptionStrategy implements ExceptionStrategy{

    @Override
    public boolean supports(Exception e) {
        // 如果传进来的时自定义异常的对象,就返回true
        return e instanceof CustomException;
    }

    @Override
    public Result handleException(Exception e) {
        // 转换为自定义异常
        CustomException ex = (CustomException) e;
        // 根据自定义异常的枚举,构建response
        return Result.fail(ex.getRespBeanEnum());
    }

}

4.GlobalExceptionHandler.java 全局异常处理

package com.sunxiansheng.exception;

import com.sunxiansheng.exception.response.RespBeanEnum;
import com.sunxiansheng.exception.response.Result;
import com.sunxiansheng.exception.strategys.ExceptionStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * Description: 全局异常处理器
 *
 * @Author sun
 * @Create 2024/5/6 15:16
 * @Version 1.0
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    // 将所有的策略都注入进来
    private final List<ExceptionStrategy> strategies;

    @Autowired // 可以省略,只有一个构造器,会默认使用这个构造器注入
    public GlobalExceptionHandler(List<ExceptionStrategy> strategies) {
        this.strategies = strategies;
    }

    /**
     * 根据不同的异常类型,决定不同的策略
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public Result exceptionHandler(Exception e) {
        log.error("Exception caught: ", e);
        for (ExceptionStrategy strategy : strategies) {
            if (strategy.supports(e)) {
                return strategy.handleException(e);
            }
        }
        return Result.fail(RespBeanEnum.ERROR);
    }

}

5.CustomException.java 自定义异常

package com.sunxiansheng.exception;

import com.sunxiansheng.exception.response.RespBeanEnum;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Description: 自定义异常类,具有响应枚举的属性,并允许传递自定义的消息。
 *
 * @Author sun
 * @Create 2024/5/6 15:15
 * @Version 1.1
 */
@Data
@NoArgsConstructor
public class CustomException extends RuntimeException {
    private RespBeanEnum respBeanEnum;
    private String customMessage;

    /**
     * 如果只传入枚举,那么使用枚举的信息,作为异常信息
     *
     * @param respBeanEnum
     */
    public CustomException(RespBeanEnum respBeanEnum) {
        super(respBeanEnum != null ? respBeanEnum.getMessage() : null);
        this.respBeanEnum = respBeanEnum;
    }

    /**
     * 如果传入枚举和自定义消息,那么使用自定义消息,作为异常信息
     *
     * @param respBeanEnum
     * @param customMessage
     */
    public CustomException(RespBeanEnum respBeanEnum, String customMessage) {
        super(customMessage != null ? customMessage : (respBeanEnum != null ? respBeanEnum.getMessage() : null));
        this.respBeanEnum = respBeanEnum;
        this.customMessage = customMessage;
    }

    @Override
    public String getMessage() {
        if (customMessage != null) {
            return customMessage;
        }
        return respBeanEnum != null ? respBeanEnum.getMessage() : super.getMessage();
    }

    @Override
    public String toString() {
        return "CustomException{" +
                "respBeanEnum=" + (respBeanEnum != null ? respBeanEnum.toString() : "null") +
                ", customMessage='" + customMessage + '\'' +
                '}';
    }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。