Anotaciones personalizadas para implementar la verificación de parámetros de datos de importación de Excel

Una anotación personalizada

1. Metaanotación

Necesitamos agregar varias metanotaciones a las anotaciones personalizadas.

@Target
@Retention
@Inherited
@Documented

1.1 Breve introducción

@Target
se usa para declarar dónde se puede usar la anotación actual

valor describir
Tipo de elemento.TIPO Se aplica a clases, interfaces (incluidos los tipos de anotaciones) y enumeraciones.
Tipo de elemento.CAMPO Se aplica a propiedades (incluidas constantes en enumeraciones)
Tipo de elemento.MÉTODO Aplicar al método
Tipo de elemento.PARÁMETRO Parámetros formales aplicados a los métodos.
Tipo de elemento.CONSTRUCTOR aplicado al constructor
Tipo de elemento.LOCAL_VARIABLE aplicado a variables locales
Tipo de elemento.ANNOTATION_TYPE Se aplica a los tipos de anotaciones
Tipo de elemento.PAQUETE aplicar al paquete
Tipo de elemento.TYPE_PARAMETER aplicado a variables de tipo
Tipo de elemento.TYPE_USE Se aplica a cualquier declaración que utilice un tipo (como tipos en declaraciones de declaración, genéricos y declaraciones de conversión)

@Retention
indica el ciclo de vida de la anotación.

tipo de ciclo de vida describir
Política de retención.FUENTE descartado en el momento de la compilación y no incluido en el archivo de clase
Política de retención. CLASE Descartado cuando se carga JVM, incluido en el archivo de clase, valor predeterminado
Política de retención.RUNTIME Cargado por la JVM, incluido en el archivo de clase y se puede obtener en tiempo de ejecución

@Inherited
indica que se utiliza la anotación @Inherited, y las subclases de la clase marcada también tendrán esta anotación.

@Document
indica que el elemento marcado por esta anotación puede documentarse mediante Javadoc o herramientas similares.

Generalmente, basta con utilizar las tres primeras al declarar anotaciones personalizadas.

2 Anotación de declaración

// {} 中可以声明多个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 "";
}

clase de enumeración

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;
	}

Esta anotación se declara

2. Herramientas de verificación

Escribir una clase de herramienta de validación

/**
 * 导入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. Verificación

3.1 Usar anotaciones personalizadas en plantillas de 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;

}

Supongo que te gusta

Origin blog.csdn.net/weixin_44931584/article/details/128956804
Recomendado
Clasificación