Excelインポートデータパラメータ検証を実装するためのカスタムアノテーション

カスタム注釈

1. メタアノテーション

カスタムアノテーションにいくつかのメタアノテーションを追加する必要があります

@Target
@Retention
@Inherited
@Documented

1.1 簡単な紹介

@Target は、
現在のアノテーションを使用できる場所を宣言するために使用されます。

価値 説明する
要素タイプ.TYPE クラス、インターフェース (注釈型を含む)、および列挙型に適用されます。
要素タイプ.フィールド プロパティ (列挙型の定数を含む) に適用されます。
要素タイプ.メソッド メソッドに適用
要素タイプ.PARAMETER メソッドに適用される仮パラメータ
要素タイプ.CONSTRUCTOR コンストラクターに適用される
ElementType.LOCAL_VARIABLE ローカル変数に適用される
ElementType.ANNOTATION_TYPE 注釈タイプに適用されます
要素タイプ.パッケージ パッケージに適用される
ElementType.TYPE_PARAMETER 型変数に適用される
要素タイプ.TYPE_USE 型を使用するすべてのステートメント (宣言ステートメント、ジェネリックス、キャスト ステートメントの型など) に適用されます。

@Retention は
アノテーションのライフサイクルを示します

ライフサイクルタイプ 説明する
RetentionPolicy.SOURCE コンパイル時に破棄され、クラスファイルには含まれません
RetentionPolicy.CLASS JVMのロード時に破棄され、クラスファイルに含まれます。デフォルト値
RetentionPolicy.RUNTIME JVM によってロードされ、クラス ファイルに含まれ、実行時に取得できます。

@Inherited は、
@Inherited アノテーションのアノテーションが使用されていることを示し、マークされたクラスのサブクラスにもこのアノテーションが付けられます。

@Document は
、このアノテーションでマークされた要素が Javadoc または同様のツールで文書化できることを示します。

一般に、カスタム アノテーションを宣言する場合は、最初の 3 つを使用するだけで十分です。

2 ステートメントのアノテーション

// {} 中可以声明多个Target类型, 这个注解我们只用在类的属性上, 只注明这一个值即可
@Target({
    
    ElementType.FIELD})
// 在运行时使用
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ExcelValid {
    
    
// 注解的属性 
// 属性声明格式 :   数据类型  属性名()  default  默认值;
// 在调用获取属性值的时候  直接通过 ' 注解对象.属性名()' 的形式
	int length() default 0;
	DataTypeEnum type() default DataTypeEnum.String;
	boolean notNull() default true;

	String lengthMessage() default "";
	String typeMessage() default "";
	String notNullMessage() default "";
}

列挙型クラス

public enum DataTypeEnum {
    
    
	Byte("Byte"),
	Short("Short"),
	Integer("Integer"),
	Long("Long"),
	Float("Float"),
	Double("Double"),
	String("String"),
	BigDecimal("BigDecimal"),
	Boolean("Boolean");


	private final String value;

	private DataTypeEnum(String value) {
    
    
		this.value = value;
	}

	public String value() {
    
    
		return this.value;
	}

このアノテーションは宣言されています

2. 検証ツール

書き込み検証ツールクラス

/**
 * 导入excel参数校验
 */
public class ExcelValidUtil {
    
    

	/**
	 * Excel导入字段校验
	 *
	 * @param object 校验的JavaBean 其属性须有自定义注解
	 */
	public static void Excelvalid(Object object) throws RuntimeException {
    
    
			valid(object,0);
	}
	
	public static void Excelvalid(Object object, int size) throws RuntimeException {
    
    
		valid(object,size);
	}
	
	private static void valid(Object object,int size) throws RuntimeException {
    
    
		String prefix = "";
		if (size > 0) {
    
    
			prefix = "第" + size + "条数据";
		}
		// 通过反射获取类的所有属性字段
		Field[] fields = object.getClass().getDeclaredFields();
		for (Field field : fields) {
    
    
			//设置可访问
			field.setAccessible(true);
			// 进行判断 如果属性上有 @ExcelIgnore 注解或者没有 @ExcelProperty则表示该字段不参数映射, 跳过
			if (field.isAnnotationPresent(ExcelIgnore.class) || !field.isAnnotationPresent(ExcelProperty.class)) {
    
    
				continue;
			}

			//属性的值
			Object fieldValue = null;
			try {
    
    
				fieldValue = field.get(object);
			} catch (IllegalAccessException e) {
    
    
				throw new RuntimeException("导入参数检查失败");
			}


			//是否包含自定义校验注解
			boolean hasValid = field.isAnnotationPresent(ExcelValid.class);
			if (hasValid ) {
    
    
			// 获取自定义注解
				ExcelValid annotation = field.getAnnotation(ExcelValid.class);
				// 非空校验
				boolean notNull = annotation.notNull(); // 获取注解notNull属性的值
				if (notNull && Objects.isNull(fieldValue)) {
    
    
					throw new RuntimeException(prefix + " " +annotation.notNullMessage());
				}
				// 类型校验
				DataTypeEnum type = annotation.type(); // 获取注解type属性的值
				if (!validType(type,fieldValue)) {
    
    
					throw new RuntimeException(prefix + " " +annotation.typeMessage());
				}
				// 长度校验
				int length = annotation.length(); // 获取注解length属性的值
				if (length > 0) {
    
    
					if (length < String.valueOf(fieldValue).length()) {
    
    
						throw new RuntimeException(prefix + " " +annotation.lengthMessage());
					}
				}
			}

		}
	}
	// 类型转换校验
	private static Boolean validType(DataTypeEnum type,Object fieldValue) {
    
    
		try {
    
    
			switch (type){
    
    
				case Byte: Byte.valueOf(String.valueOf(fieldValue)); break;
				case Short: Short.valueOf(String.valueOf(fieldValue)); break;
				case Integer: Integer.valueOf(String.valueOf(fieldValue)); break;
				case Long: Long.valueOf(String.valueOf(fieldValue)); break;
				case Float: Float.valueOf(String.valueOf(fieldValue)); break;
				case Double: Double.valueOf(String.valueOf(fieldValue)); break;
				case String: String.valueOf(fieldValue); break;
				case BigDecimal: new BigDecimal(String.valueOf(fieldValue)); break;
				case Boolean: Boolean.valueOf(String.valueOf(fieldValue)); break;
				default: break;
			}
		}catch (Exception e){
    
    
		// 转换失败返回false
			return false;
		}
		return true;
	}
}

3. 検証

3.1 Excel テンプレートでカスタム注釈を使用する

@Data
@ColumnWidth(25)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class GoodsExcel implements Serializable {
    
    
	private static final long serialVersionUID = 1L;


	@ExcelProperty("租户编号(可空)")
	@ExcelValid(length = 255,lengthMessage = "分类编号 过长",
	notNull = false,
	type = DataTypeEnum.String,typeMessage = "分类编号 数据格式异常")
	private String tenantId;

// 其中notnull 默认值是 true, 可空字段要填成 false
// type 默认类型是string,   可省略不写

// 默认值信息可省略
	@ExcelProperty("货品名称")
	@ExcelValid(length = 255,lengthMessage = "货品名称 过长",
		notNullMessage = "货品名称 不可为空"
	)
	private String goodsName;

// 没有 ExcelProperty 注解 不会校验该字段
	@ColumnWidth(30)
	@ExcelValid(length = 2,lengthMessage = "是否一物一码 过长",
		notNullMessage = "是否一物一码 不可为空"
	)
	private String isNotEditStr;

// 有ExcelIgnore注解 不会校验该字段
	@ExcelProperty("是否一物一码(是/否)")
	@ExcelIgnore
	private Integer isNotEdit;

}

おすすめ

転載: blog.csdn.net/weixin_44931584/article/details/128956804