异常码规范、国际化

目的:断言统一封装异常码,国际化支持,调用方式

配置i18n异常码映射文件



根据项目BaseException中对编码进行转换


1.约定异常码字段(BaseErrorModule 约定各服务ModuleId等)


/**
 * 基础错误编号
 *
 * @author zj
 * @date 2024/10/02
 */
public interface BaseErrorCode {

    /**
     * 获取错误模块
     *
     * @return {@link BaseErrorModule}
     */
    BaseErrorModule getErrorModule();

    /**
     * 获取编号
     *
     * @return {@link String}
     */
    String getCode();

    /**
     * 获取消息
     *
     * @return {@link String}
     */
    String getMessage();

    /**
     * 获取解决方案
     *
     * @return {@link String}
     */
    String getSolution();

}

2.约定异常码抽象类


/**
 * 常见错误编号
 *
 * @author zj
 * @date 2024/10/02
 */
@Data
public abstract class AbstractErrorCode implements BaseErrorCode {

    /**
     * 编号
     */
    private String code;
    /**
     * 消息
     */
    private String message;

    /**
     * 错误模块
     */
    private BaseErrorModule errorModule;

    /**
     * 解决方案
     */
    private String solution;

    /**
     * 错误编号信息
     *
     * @param code    编号
     * @param message 消息
     */
    public AbstractErrorCode(String code, String message) {
        this.code = code;
        this.message = message;
    }


    /**
     * 错误编号信息
     *
     * @param code        编号
     * @param message     消息
     * @param solution    解决方案
     */
    public AbstractErrorCode(String code, String message, String solution) {
        this.code = code;
        this.message = message;
        this.solution = solution;
    }

    /**
     * 默认模块,可被子类覆盖
     */
    @Override
    public BaseErrorModule getErrorModule() {
        return ErrorModule.UN_KNOW;
    }

}

3.异常码(通常模块维度异常码,也有Domain维度异常码)

package com.gx.common.exception;

/**
 * 客户关系管理错误编号常数
 *
 * @author zj
 * @date 2024/10/02
 */
public class CrmErrorCodeConstants extends CommonErrorCode {

    /**
     * 客户【{}】放入公海失败,原因:客户已锁定
     */
    CrmErrorCodeConstants CUSTOMER_LOCKED_PUT_POOL_FAIL = new CrmErrorCodeConstants("B00001", "客户【{}】放入公海失败,原因:客户已锁定");


    /**
     * 客户关系管理错误编号常数
     *
     * @param code    编号
     * @param message 消息
     */
    public CrmErrorCodeConstants(String code, String message) {
        super(code, message);
    }

    /**
     * 客户关系管理错误编号常数
     *
     * @param code     编号
     * @param message  消息
     * @param solution 解决方案
     */
    public CrmErrorCodeConstants(String code, String message, String solution) {
        super(code, message, solution);
    }

    @Override
    public BaseErrorModule getErrorModule() {
        return ErrorModule.CRM;
    }


}

3.断言工具类


/**
 * 断言封装(基于HuTool改造)
 * 断言某些对象或值是否符合规定,否则抛出异常。经常用于做变量检查
 *
 * @author zj
 */
public class AssertUtil {

    /**
     * 默认错误
     */
    public static final CommonErrorCode DEFAULT_ERROR_CODE = CommonErrorCode.SYS_EXEC_ERROR;


    /**
     * 断言是否为真,如果为 {@code false} 抛出给定的异常<br>
     *
     * <pre class="code">
     * Assert.isTrue(i &gt; 0, ServiceException::new);
     * </pre>
     *
     * @param <X>        异常类型
     * @param expression 布尔值
     * @param supplier   指定断言不通过时抛出的异常
     * @throws X if expression is {@code false}
     */
    public static <X extends Throwable> void isTrue(boolean expression, Supplier<? extends X> supplier) throws X {
        if (false == expression) {
            throw supplier.get();
        }
    }

    /**
     * 断言是否为真,如果为 {@code false} 抛出 {@code ServiceException} 异常<br>
     *
     * <pre class="code">
     * Assert.isTrue(i &gt; 0, "The value must be greater than zero");
     * </pre>
     *
     * @param expression 布尔值
     * @throws ServiceException if expression is {@code false}
     */
    public static void isTrue(boolean expression, AbstractErrorCode errorCode) throws ServiceException {
        isTrue(expression, () -> new ServiceException(errorCode));
    }

    /**
     * 断言是否为真,如果为 {@code false} 抛出 {@code ServiceException} 异常<br>
     *
     * <pre class="code">
     * Assert.isTrue(i &gt; 0);
     * </pre>
     *
     * @param expression 布尔值
     * @throws ServiceException if expression is {@code false}
     */
    public static void isTrue(boolean expression) throws ServiceException {
        isTrue(expression, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言是否为假,如果为 {@code true} 抛出指定类型异常<br>
     * 并使用指定的函数获取错误信息返回
     * <pre class="code">
     *  Assert.isFalse(i &gt; 0, ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return");
     *  });
     * </pre>
     *
     * @param <X>           异常类型
     * @param expression    布尔值
     * @param errorSupplier 指定断言不通过时抛出的异常
     * @throws X if expression is {@code false}
     */
    public static <X extends Throwable> void isFalse(boolean expression, Supplier<X> errorSupplier) throws X {
        if (expression) {
            throw errorSupplier.get();
        }
    }

    /**
     * 断言是否为假,如果为 {@code true} 抛出 {@code ServiceException} 异常<br>
     *
     * <pre class="code">
     * Assert.isFalse(i &lt; 0, "The value must not be negative");
     * </pre>
     *
     * @param expression 布尔值
     * @throws ServiceException if expression is {@code false}
     */
    public static void isFalse(boolean expression, AbstractErrorCode errorCode) throws ServiceException {
        isFalse(expression, () -> new ServiceException(errorCode));
    }

    /**
     * 断言是否为假,如果为 {@code true} 抛出 {@code ServiceException} 异常<br>
     *
     * <pre class="code">
     * Assert.isFalse(i &lt; 0);
     * </pre>
     *
     * @param expression 布尔值
     * @throws ServiceException if expression is {@code false}
     */
    public static void isFalse(boolean expression) throws ServiceException {
        isFalse(expression, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言对象是否为{@code null} ,如果不为{@code null} 抛出指定类型异常
     * 并使用指定的函数获取错误信息返回
     * <pre class="code">
     * Assert.isNull(value, ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return");
     *  });
     * </pre>
     *
     * @param <X>           异常类型
     * @param object        被检查的对象
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @throws X if the object is not {@code null}
     */
    public static <X extends Throwable> void isNull(Object object, Supplier<X> errorSupplier) throws X {
        if (null != object) {
            throw errorSupplier.get();
        }
    }

    /**
     * 断言对象是否为{@code null} ,如果不为{@code null} 抛出{@link ServiceException} 异常
     *
     * <pre class="code">
     * Assert.isNull(value, "The value must be null");
     * </pre>
     *
     * @param object 被检查的对象
     * @throws ServiceException if the object is not {@code null}
     */
    public static void isNull(Object object, AbstractErrorCode errorCode) throws ServiceException {
        isNull(object, () -> new ServiceException(errorCode));
    }

    /**
     * 断言对象是否为{@code null} ,如果不为{@code null} 抛出{@link ServiceException} 异常
     *
     * <pre class="code">
     * Assert.isNull(value);
     * </pre>
     *
     * @param object 被检查对象
     * @throws ServiceException if the object is not {@code null}
     */
    public static void isNull(Object object) throws ServiceException {
        isNull(object, DEFAULT_ERROR_CODE);
    }

    // ----------------------------------------------------------------------------------------------------------- Check not null

    /**
     * 断言对象是否不为{@code null} ,如果为{@code null} 抛出指定类型异常
     * 并使用指定的函数获取错误信息返回
     * <pre class="code">
     * Assert.notNull(clazz, ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return");
     *  });
     * </pre>
     *
     * @param <T>           被检查对象泛型类型
     * @param <X>           异常类型
     * @param object        被检查对象
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 被检查后的对象
     * @throws X if the object is {@code null}
     */
    public static <T, X extends Throwable> T notNull(T object, Supplier<X> errorSupplier) throws X {
        if (null == object) {
            throw errorSupplier.get();
        }
        return object;
    }

    /**
     * 断言对象是否不为{@code null} ,如果为{@code null} 抛出{@link ServiceException} 异常 Assert that an object is not {@code null} .
     *
     * <pre class="code">
     * Assert.notNull(clazz, "The class must not be null");
     * </pre>
     *
     * @param <T>    被检查对象泛型类型
     * @param object 被检查对象
     * @return 被检查后的对象
     * @throws ServiceException if the object is {@code null}
     */
    public static <T> T notNull(T object, AbstractErrorCode errorCode) throws ServiceException {
        return notNull(object, () -> new ServiceException(errorCode));
    }

    /**
     * 断言对象是否不为{@code null} ,如果为{@code null} 抛出{@link ServiceException} 异常
     *
     * <pre class="code">
     * Assert.notNull(clazz);
     * </pre>
     *
     * @param <T>    被检查对象类型
     * @param object 被检查对象
     * @return 非空对象
     * @throws ServiceException if the object is {@code null}
     */
    public static <T> T notNull(T object) throws ServiceException {
        return notNull(object, DEFAULT_ERROR_CODE);
    }

    // ----------------------------------------------------------------------------------------------------------- Check empty

    /**
     * 检查给定字符串是否为空,为空抛出自定义异常,并使用指定的函数获取错误信息返回。
     * <pre class="code">
     * Assert.notEmpty(name, ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return");
     *  });
     * </pre>
     *
     * @param <X>           异常类型
     * @param <T>           字符串类型
     * @param text          被检查字符串
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 非空字符串
     * @throws X 被检查字符串为空抛出此异常
     * @see StrUtil#isNotEmpty(CharSequence)
     */
    public static <T extends CharSequence, X extends Throwable> T notEmpty(T text, Supplier<X> errorSupplier) throws X {
        if (StrUtil.isEmpty(text)) {
            throw errorSupplier.get();
        }
        return text;
    }

    /**
     * 检查给定字符串是否为空,为空抛出 {@link ServiceException}
     *
     * <pre class="code">
     * Assert.notEmpty(name, "Name must not be empty");
     * </pre>
     *
     * @param <T>  字符串类型
     * @param text 被检查字符串
     * @return 非空字符串
     * @throws ServiceException 被检查字符串为空
     * @see StrUtil#isNotEmpty(CharSequence)
     */
    public static <T extends CharSequence> T notEmpty(T text, AbstractErrorCode errorCode) throws ServiceException {
        return notEmpty(text, () -> new ServiceException(errorCode));
    }

    /**
     * 检查给定字符串是否为空,为空抛出 {@link ServiceException}
     *
     * <pre class="code">
     * Assert.notEmpty(name);
     * </pre>
     *
     * @param <T>  字符串类型
     * @param text 被检查字符串
     * @return 被检查的字符串
     * @throws ServiceException 被检查字符串为空
     * @see StrUtil#isNotEmpty(CharSequence)
     */
    public static <T extends CharSequence> T notEmpty(T text) throws ServiceException {
        return notEmpty(text, DEFAULT_ERROR_CODE);
    }

    /**
     * 检查给定字符串是否为空白(null、空串或只包含空白符),为空抛出自定义异常。
     * 并使用指定的函数获取错误信息返回
     * <pre class="code">
     * Assert.notBlank(name, ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return");
     *  });
     * </pre>
     *
     * @param <X>              异常类型
     * @param <T>              字符串类型
     * @param text             被检查字符串
     * @param errorMsgSupplier 错误抛出异常附带的消息生产接口
     * @return 非空字符串
     * @throws X 被检查字符串为空白
     * @see StrUtil#isNotBlank(CharSequence)
     */
    public static <T extends CharSequence, X extends Throwable> T notBlank(T text, Supplier<X> errorMsgSupplier) throws X {
        if (StrUtil.isBlank(text)) {
            throw errorMsgSupplier.get();
        }
        return text;
    }

    /**
     * 检查给定字符串是否为空白(null、空串或只包含空白符),为空抛出 {@link ServiceException}
     *
     * <pre class="code">
     * Assert.notBlank(name, "Name must not be blank");
     * </pre>
     *
     * @param <T>  字符串类型
     * @param text 被检查字符串
     * @return 非空字符串
     * @throws ServiceException 被检查字符串为空白
     * @see StrUtil#isNotBlank(CharSequence)
     */
    public static <T extends CharSequence> T notBlank(T text, AbstractErrorCode errorCode) throws ServiceException {
        return notBlank(text, () -> new ServiceException(errorCode));
    }

    /**
     * 检查给定字符串是否为空白(null、空串或只包含空白符),为空抛出 {@link ServiceException}
     *
     * <pre class="code">
     * Assert.notBlank(name);
     * </pre>
     *
     * @param <T>  字符串类型
     * @param text 被检查字符串
     * @return 非空字符串
     * @throws ServiceException 被检查字符串为空白
     * @see StrUtil#isNotBlank(CharSequence)
     */
    public static <T extends CharSequence> T notBlank(T text) throws ServiceException {
        return notBlank(text, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言给定字符串是否不被另一个字符串包含(即是否为子串)
     * 并使用指定的函数获取错误信息返回
     * <pre class="code">
     * Assert.notContain(name, "rod", ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return ");
     *  });
     * </pre>
     *
     * @param <T>           字符串类型
     * @param <X>           异常类型
     * @param textToSearch  被搜索的字符串
     * @param substring     被检查的子串
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 被检查的子串
     * @throws X 非子串抛出异常
     * @see StrUtil#contains(CharSequence, CharSequence)
     */
    public static <T extends CharSequence, X extends Throwable> T notContain(CharSequence textToSearch, T substring, Supplier<X> errorSupplier) throws X {
        if (StrUtil.contains(textToSearch, substring)) {
            throw errorSupplier.get();
        }
        return substring;
    }

    /**
     * 断言给定字符串是否不被另一个字符串包含(即是否为子串)
     *
     * <pre class="code">
     * Assert.notContain(name, "rod", "Name must not contain 'rod'");
     * </pre>
     *
     * @param textToSearch 被搜索的字符串
     * @param substring    被检查的子串
     * @return 被检查的子串
     * @throws ServiceException 非子串抛出异常
     */
    public static String notContain(String textToSearch, String substring, AbstractErrorCode errorCode) throws ServiceException {
        return notContain(textToSearch, substring, () -> new ServiceException(errorCode));
    }

    /**
     * 断言给定字符串是否不被另一个字符串包含(即是否为子串)
     *
     * <pre class="code">
     * Assert.notContain(name, "rod");
     * </pre>
     *
     * @param textToSearch 被搜索的字符串
     * @param substring    被检查的子串
     * @return 被检查的子串
     * @throws ServiceException 非子串抛出异常
     */
    public static String notContain(String textToSearch, String substring) throws ServiceException {
        return notContain(textToSearch, substring, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言给定数组是否包含元素,数组必须不为 {@code null} 且至少包含一个元素
     * 并使用指定的函数获取错误信息返回
     *
     * <pre class="code">
     * Assert.notEmpty(array, ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return");
     *  });
     * </pre>
     *
     * @param <T>           数组元素类型
     * @param <X>           异常类型
     * @param array         被检查的数组
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 被检查的数组
     * @throws X if the object array is {@code null} or has no elements
     * @see ArrayUtil#isNotEmpty(Object[])
     */
    public static <T, X extends Throwable> T[] notEmpty(T[] array, Supplier<X> errorSupplier) throws X {
        if (ArrayUtil.isEmpty(array)) {
            throw errorSupplier.get();
        }
        return array;
    }

    /**
     * 断言给定数组是否包含元素,数组必须不为 {@code null} 且至少包含一个元素
     *
     * <pre class="code">
     * Assert.notEmpty(array, "The array must have elements");
     * </pre>
     *
     * @param <T>   数组元素类型
     * @param array 被检查的数组
     * @return 被检查的数组
     * @throws ServiceException if the object array is {@code null} or has no elements
     */
    public static <T> T[] notEmpty(T[] array, AbstractErrorCode errorCode) throws ServiceException {
        return notEmpty(array, () -> new ServiceException(errorCode));
    }

    /**
     * 断言给定数组是否包含元素,数组必须不为 {@code null} 且至少包含一个元素
     *
     * <pre class="code">
     * Assert.notEmpty(array, "The array must have elements");
     * </pre>
     *
     * @param <T>   数组元素类型
     * @param array 被检查的数组
     * @return 被检查的数组
     * @throws ServiceException if the object array is {@code null} or has no elements
     */
    public static <T> T[] notEmpty(T[] array) throws ServiceException {
        return notEmpty(array, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言给定数组是否不包含{@code null}元素,如果数组为空或 {@code null}将被认为不包含
     * 并使用指定的函数获取错误信息返回
     * <pre class="code">
     * Assert.noNullElements(array, ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return ");
     *  });
     * </pre>
     *
     * @param <T>           数组元素类型
     * @param <X>           异常类型
     * @param array         被检查的数组
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 被检查的数组
     * @throws X if the object array contains a {@code null} element
     * @see ArrayUtil#hasNull(Object[])
     */
    public static <T, X extends Throwable> T[] noNullElements(T[] array, Supplier<X> errorSupplier) throws X {
        if (ArrayUtil.hasNull(array)) {
            throw errorSupplier.get();
        }
        return array;
    }

    /**
     * 断言给定数组是否不包含{@code null}元素,如果数组为空或 {@code null}将被认为不包含
     *
     * <pre class="code">
     * Assert.noNullElements(array, "The array must not have null elements");
     * </pre>
     *
     * @param <T>   数组元素类型
     * @param array 被检查的数组
     * @return 被检查的数组
     * @throws ServiceException if the object array contains a {@code null} element
     */
    public static <T> T[] noNullElements(T[] array, AbstractErrorCode errorCode) throws ServiceException {
        return noNullElements(array, () -> new ServiceException(errorCode));
    }

    /**
     * 断言给定数组是否不包含{@code null}元素,如果数组为空或 {@code null}将被认为不包含
     *
     * <pre class="code">
     * Assert.noNullElements(array);
     * </pre>
     *
     * @param <T>   数组元素类型
     * @param array 被检查的数组
     * @return 被检查的数组
     * @throws ServiceException if the object array contains a {@code null} element
     */
    public static <T> T[] noNullElements(T[] array) throws ServiceException {
        return noNullElements(array, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言给定集合非空
     * 并使用指定的函数获取错误信息返回
     * <pre class="code">
     * Assert.notEmpty(collection, ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return");
     *  });
     * </pre>
     *
     * @param <E>           集合元素类型
     * @param <T>           集合类型
     * @param <X>           异常类型
     * @param collection    被检查的集合
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 非空集合
     * @throws X if the collection is {@code null} or has no elements
     * @see CollUtil#isNotEmpty(Iterable)
     */
    public static <E, T extends Iterable<E>, X extends Throwable> T notEmpty(T collection, Supplier<X> errorSupplier) throws X {
        if (CollUtil.isEmpty(collection)) {
            throw errorSupplier.get();
        }
        return collection;
    }

    /**
     * 断言给定集合非空
     *
     * <pre class="code">
     * Assert.notEmpty(collection, "Collection must have elements");
     * </pre>
     *
     * @param <E>        集合元素类型
     * @param <T>        集合类型
     * @param collection 被检查的集合
     * @return 非空集合
     * @throws ServiceException if the collection is {@code null} or has no elements
     */
    public static <E, T extends Iterable<E>> T notEmpty(T collection, AbstractErrorCode errorCode) throws ServiceException {
        return notEmpty(collection, () -> new ServiceException(errorCode));
    }

    /**
     * 断言给定集合非空
     *
     * <pre class="code">
     * Assert.notEmpty(collection);
     * </pre>
     *
     * @param <E>        集合元素类型
     * @param <T>        集合类型
     * @param collection 被检查的集合
     * @return 被检查集合
     * @throws ServiceException if the collection is {@code null} or has no elements
     */
    public static <E, T extends Iterable<E>> T notEmpty(T collection) throws ServiceException {
        return notEmpty(collection, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言给定Map非空
     * 并使用指定的函数获取错误信息返回
     * <pre class="code">
     * Assert.notEmpty(map, ()-&gt;{
     *      // to query relation message
     *      return new ServiceException("relation message to return");
     *  });
     * </pre>
     *
     * @param <K>           Key类型
     * @param <V>           Value类型
     * @param <T>           Map类型
     * @param <X>           异常类型
     * @param map           被检查的Map
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 被检查的Map
     * @throws X if the map is {@code null} or has no entries
     * @see MapUtil#isNotEmpty(Map)
     */
    public static <K, V, T extends Map<K, V>, X extends Throwable> T notEmpty(T map, Supplier<X> errorSupplier) throws X {
        if (MapUtil.isEmpty(map)) {
            throw errorSupplier.get();
        }
        return map;
    }

    /**
     * 断言给定Map非空
     *
     * <pre class="code">
     * Assert.notEmpty(map, "Map must have entries");
     * </pre>
     *
     * @param <K> Key类型
     * @param <V> Value类型
     * @param <T> Map类型
     * @param map 被检查的Map
     * @return 被检查的Map
     * @throws ServiceException if the map is {@code null} or has no entries
     */
    public static <K, V, T extends Map<K, V>> T notEmpty(T map, AbstractErrorCode errorCode) throws ServiceException {
        return notEmpty(map, () -> new ServiceException(errorCode));
    }

    /**
     * 断言给定Map非空
     *
     * <pre class="code">
     * Assert.notEmpty(map, "Map must have entries");
     * </pre>
     *
     * @param <K> Key类型
     * @param <V> Value类型
     * @param <T> Map类型
     * @param map 被检查的Map
     * @return 被检查的Map
     * @throws ServiceException if the map is {@code null} or has no entries
     */
    public static <K, V, T extends Map<K, V>> T notEmpty(T map) throws ServiceException {
        return notEmpty(map, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言给定对象是否是给定类的实例
     *
     * <pre class="code">
     * Assert.instanceOf(Foo.class, foo);
     * </pre>
     *
     * @param <T>  被检查对象泛型类型
     * @param type 被检查对象匹配的类型
     * @param obj  被检查对象
     * @return 被检查的对象
     * @throws ServiceException if the object is not an instance of clazz
     * @see Class#isInstance(Object)
     */
    public static <T> T isInstanceOf(Class<?> type, T obj) {
        return isInstanceOf(type, obj, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言给定对象是否是给定类的实例
     *
     * <pre class="code">
     * Assert.instanceOf(Foo.class, foo, "foo must be an instance of class Foo");
     * </pre>
     *
     * @param <T>  被检查对象泛型类型
     * @param type 被检查对象匹配的类型
     * @param obj  被检查对象
     * @return 被检查对象
     * @throws ServiceException if the object is not an instance of clazz
     * @see Class#isInstance(Object)
     */
    public static <T> T isInstanceOf(Class<?> type, T obj, AbstractErrorCode errorCode) throws ServiceException {
        notNull(type, DEFAULT_ERROR_CODE);
        if (false == type.isInstance(obj)) {
            throw new ServiceException(errorCode);
        }
        return obj;
    }

    /**
     * 断言 {@code superType.isAssignableFrom(subType)} 是否为 {@code true}.
     *
     * <pre class="code">
     * Assert.isAssignable(Number.class, myClass);
     * </pre>
     *
     * @param superType 需要检查的父类或接口
     * @param subType   需要检查的子类
     * @throws ServiceException 如果子类非继承父类,抛出此异常
     */
    public static void isAssignable(Class<?> superType, Class<?> subType) throws ServiceException {
        isAssignable(superType, subType, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言 {@code superType.isAssignableFrom(subType)} 是否为 {@code true}.
     *
     * <pre class="code">
     * Assert.isAssignable(Number.class, myClass, "myClass must can be assignable to class Number");
     * </pre>
     *
     * @param superType 需要检查的父类或接口
     * @param subType   需要检查的子类
     * @throws ServiceException 如果子类非继承父类,抛出此异常
     */
    public static void isAssignable(Class<?> superType, Class<?> subType, AbstractErrorCode errorCode) throws ServiceException {
        notNull(superType, DEFAULT_ERROR_CODE);
        if (subType == null || !superType.isAssignableFrom(subType)) {
            throw new ServiceException(errorCode);
        }
    }

    /**
     * 检查boolean表达式,当检查结果为false时抛出 {@code IllegalStateException}。
     * 并使用指定的函数获取错误信息返回
     * <pre class="code">
     * Assert.state(id == null, ()-&gt;{
     *      // to query relation message
     *      return "relation message to return ";
     *  });
     * </pre>
     *
     * @param expression       boolean 表达式
     * @param errorMsgSupplier 错误抛出异常附带的消息生产接口
     * @throws IllegalStateException 表达式为 {@code false} 抛出此异常
     */
    public static void state(boolean expression, Supplier<String> errorMsgSupplier) throws IllegalStateException {
        if (false == expression) {
            throw new ServiceException(errorMsgSupplier.get());
        }
    }

    /**
     * 检查boolean表达式,当检查结果为false时抛出 {@code IllegalStateException}。
     *
     * <pre class="code">
     * Assert.state(id == null, "The id property must not already be initialized");
     * </pre>
     *
     * @param expression boolean 表达式
     * @throws IllegalStateException 表达式为 {@code false} 抛出此异常
     */
    public static void state(boolean expression, AbstractErrorCode errorCode) throws IllegalStateException {
        if (false == expression) {
            throw new ServiceException(errorCode);
        }
    }

    /**
     * 检查boolean表达式,当检查结果为false时抛出 {@code IllegalStateException}。
     *
     * <pre class="code">
     * Assert.state(id == null);
     * </pre>
     *
     * @param expression boolean 表达式
     * @throws IllegalStateException 表达式为 {@code false} 抛出此异常
     */
    public static void state(boolean expression) throws IllegalStateException {
        state(expression, DEFAULT_ERROR_CODE);
    }


    /**
     * 检查值是否在指定范围内
     *
     * @param <X>           异常类型
     * @param value         值
     * @param min           最小值(包含)
     * @param max           最大值(包含)
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 经过检查后的值
     * @throws X if value is out of bound
     */
    public static <X extends Throwable> int checkBetween(int value, int min, int max, Supplier<? extends X> errorSupplier) throws X {
        if (value < min || value > max) {
            throw errorSupplier.get();
        }

        return value;
    }

    /**
     * 检查值是否在指定范围内
     *
     * @param value 值
     * @param min   最小值(包含)
     * @param max   最大值(包含)
     * @return 经过检查后的值
     */
    public static int checkBetween(int value, int min, int max, AbstractErrorCode errorCode) {
        return checkBetween(value, min, max, () -> new ServiceException(errorCode));
    }


    /**
     * 检查值是否在指定范围内
     *
     * @param <X>           异常类型
     * @param value         值
     * @param min           最小值(包含)
     * @param max           最大值(包含)
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 经过检查后的值
     * @throws X if value is out of bound
     */
    public static <X extends Throwable> long checkBetween(long value, long min, long max, Supplier<? extends X> errorSupplier) throws X {
        if (value < min || value > max) {
            throw errorSupplier.get();
        }

        return value;
    }

    /**
     * 检查值是否在指定范围内
     *
     * @param value 值
     * @param min   最小值(包含)
     * @param max   最大值(包含)
     * @return 经过检查后的值
     */
    public static long checkBetween(long value, long min, long max, AbstractErrorCode errorCode) {
        return checkBetween(value, min, max, () -> new ServiceException(errorCode));
    }

    /**
     * 检查值是否在指定范围内
     *
     * @param <X>           异常类型
     * @param value         值
     * @param min           最小值(包含)
     * @param max           最大值(包含)
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @return 经过检查后的值
     * @throws X if value is out of bound
     */
    public static <X extends Throwable> double checkBetween(double value, double min, double max, Supplier<? extends X> errorSupplier) throws X {
        if (value < min || value > max) {
            throw errorSupplier.get();
        }

        return value;
    }


    /**
     * 断言两个对象是否不相等,如果两个对象相等 抛出ServiceException 异常
     * <pre class="code">
     *   Assert.notEquals(obj1,obj2);
     * </pre>
     *
     * @param obj1 对象1
     * @param obj2 对象2
     * @throws ServiceException obj1 must be not equals obj2
     */
    public static void notEquals(Object obj1, Object obj2) {
        notEquals(obj1, obj2, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言两个对象是否不相等,如果两个对象相等 抛出ServiceException 异常
     * <pre class="code">
     *   Assert.notEquals(obj1,obj2,"obj1 must be not equals obj2");
     * </pre>
     *
     * @param obj1 对象1
     * @param obj2 对象2
     * @throws ServiceException obj1 must be not equals obj2
     */
    public static void notEquals(Object obj1, Object obj2, AbstractErrorCode errorCode) throws ServiceException {
        notEquals(obj1, obj2, () -> new ServiceException(errorCode));
    }

    /**
     * 断言两个对象是否不相等,如果两个对象相等,抛出指定类型异常,并使用指定的函数获取错误信息返回
     *
     * @param obj1          对象1
     * @param obj2          对象2
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @param <X>           异常类型
     * @throws X obj1 must be not equals obj2
     */
    public static <X extends Throwable> void notEquals(Object obj1, Object obj2, Supplier<X> errorSupplier) throws X {
        if (ObjectUtil.equals(obj1, obj2)) {
            throw errorSupplier.get();
        }
    }
    // ----------------------------------------------------------------------------------------------------------- Check not equals

    /**
     * 断言两个对象是否相等,如果两个对象不相等 抛出ServiceException 异常
     * <pre class="code">
     *   Assert.isEquals(obj1,obj2);
     * </pre>
     *
     * @param obj1 对象1
     * @param obj2 对象2
     * @throws ServiceException obj1 must be equals obj2
     */
    public static void equals(Object obj1, Object obj2) {
        equals(obj1, obj2, DEFAULT_ERROR_CODE);
    }

    /**
     * 断言两个对象是否相等,如果两个对象不相等 抛出ServiceException 异常
     * <pre class="code">
     *   Assert.isEquals(obj1,obj2,"obj1 must be equals obj2");
     * </pre>
     *
     * @param obj1 对象1
     * @param obj2 对象2
     * @throws ServiceException obj1 must be equals obj2
     */
    public static void equals(Object obj1, Object obj2, AbstractErrorCode errorCode) throws ServiceException {
        equals(obj1, obj2, () -> new ServiceException(errorCode));
    }

    /**
     * 断言两个对象是否相等,如果两个对象不相等,抛出指定类型异常,并使用指定的函数获取错误信息返回
     *
     * @param obj1          对象1
     * @param obj2          对象2
     * @param errorSupplier 错误抛出异常附带的消息生产接口
     * @param <X>           异常类型
     * @throws X obj1 must be equals obj2
     */
    public static <X extends Throwable> void equals(Object obj1, Object obj2, Supplier<X> errorSupplier) throws X {
        if (ObjectUtil.notEqual(obj1, obj2)) {
            throw errorSupplier.get();
        }
    }

    // ----------------------------------------------------------------------------------------------------------- Check is equals


    /**
     * 错误的下标时显示的消息
     *
     * @param index  下标
     * @param size   长度
     * @param desc   异常时的消息模板
     * @param params 参数列表
     * @return 消息
     */
    private static String badIndexMsg(int index, int size, String desc, Object... params) {
        if (index < 0) {
            return StrUtil.format("{} ({}) must not be negative", StrUtil.format(desc, params), index);
        } else if (size < 0) {
            throw new IllegalArgumentException("negative size: " + size);
        } else { // index >= size
            return StrUtil.format("{} ({}) must be less than size ({})", StrUtil.format(desc, params), index, size);
        }
    }
    // -------------------------------------------------------------------------------------------------------------------------------------------- Private method end

4.异常码转换

package com.gx.common.utils.i18n;

import cn.hutool.extra.spring.SpringUtil;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;


/**
 * 国际化工具类
 *
 * @author zj
 * @date 2024/03/20
 */
public class MessageUtils {
    /**
     * 消息来源
     */
    private static final MessageSource MESSAGE_SOURCE;

    static {
        MESSAGE_SOURCE = SpringUtil.getBean("messageSource");
    }

    /**
     * 获取消息
     *
     * @param code 编号
     * @return {@link String }
     */
    public static String getMessage(String code){
        return getMessage(code, new String[0]);
    }

    /**
     * 获取消息
     *
     * @param code   编号
     * @param params 参数
     * @return {@link String }
     */
    public static String getMessage(String code, String... params){
        return MESSAGE_SOURCE.getMessage(code, params, LocaleContextHolder.getLocale());
    }
}

菜单语言相关维护进表,通过语言字段区分

内容概要:本资源聚焦于配电网在发生故障后的两阶段鲁棒恢复研究,旨在提升电力系统在不确定性条件下的恢复能力与运行可靠性。研究采用两阶段优化方法,第一阶段进行预恢复决策,如网络重构、分布式电源出力调整等,以最小化预期损失;第二阶段则针对实际发生的故障场景实施校正控制,利用鲁棒优化理论应对负荷波动、新能源出力不确定性等因素,确保恢复方案的可行性与强健性。资源提供了完整的Matlab代实现,复现了相关顶刊研究成果,便于使用者深入理解模型构建、算法求解及仿真分析全过程。; 适合人群:具备电力系统分析、优化理论基础及Matlab编程能力的研究生、科研人员及电力行业工程师。; 使用场景及目标:① 学习并掌握配电网故障恢复的先进优化方法,特别是两阶段鲁棒优化模型的构建与应用;② 复现和验证顶刊论文中的算法,为自身科研工作提供技术参考和代基础;③ 将所学方法拓展应用于微电网、主动配电网等新型电力系统的可靠性评估与优化调度研究。; 阅读建议:学习者应结合提供的Matlab代,仔细研读模型的数学公式与求解逻辑,重点关注不确定性建模、两阶段决策变量的设定以及鲁棒对等转换技巧。建议在掌握基础案例后,尝试修改参数或引入新的约束条件进行扩展研究,以深化理解并提升创新能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值