This commit is contained in:
Hua
2024-07-20 14:34:56 +08:00
commit d6ea3c61dc
23 changed files with 908 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

7
.idea/encodings.xml generated Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

6
.idea/git_toolbox_blame.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitToolBoxBlameSettings">
<option name="version" value="2" />
</component>
</project>

10
.idea/material_theme_project_new.xml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="userId" value="-6730a49d:190ceb01e77:-7fb9" />
</MTProjectMetadataState>
</option>
</component>
</project>

14
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="oracle-21.0.2" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

124
.idea/uiDesigner.xml generated Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

45
pom.xml Normal file
View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hua</groupId>
<artifactId>utils</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<springContext.version>5.2.1.RELEASE</springContext.version>
<hutool.version>5.8.26</hutool.version>
<reflections.version>0.9.10</reflections.version>
<validation.version>2.0.1.Final</validation.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springContext.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${validation.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,13 @@
package com.hua.annotation;
import java.lang.annotation.*;
/**
* @author Hua
* @since 2024/7/18 下午2:43
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Handles {
Class<? extends Annotation> value();
}

View File

@ -0,0 +1,42 @@
package com.hua.test.valid;
import com.hua.valid.annotation.ConditionNotNull;
/**
* @author Hua
* @since 2024/7/18 下午2:43
*/
public class Student {
@ConditionNotNull(test = "teaName == '王老师' and teaAge == 28 and teaSex == 1", message = "老师名字为王老师年龄为18性别为1的时候 name不能为null")
private String name;
private int age;
private int sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}

View File

@ -0,0 +1,56 @@
package com.hua.test.valid;
import com.hua.valid.annotation.ValidPlus;
import javax.validation.Valid;
import java.util.List;
/**
* @author Hua
* @since 2024/7/18 下午2:43
*/
@ValidPlus
public class Teach {
private String teaName;
private int teaAge;
private int teaSex;
@Valid
private List<Student> listStu;
public String getTeaName() {
return teaName;
}
public void setTeaName(String teaName) {
this.teaName = teaName;
}
public int getTeaAge() {
return teaAge;
}
public void setTeaAge(int teaAge) {
this.teaAge = teaAge;
}
public int getTeaSex() {
return teaSex;
}
public void setTeaSex(int teaSex) {
this.teaSex = teaSex;
}
public List<Student> getListStu() {
return listStu;
}
public void setListStu(List<Student> listStu) {
this.listStu = listStu;
}
}

View File

@ -0,0 +1,49 @@
package com.hua.test.valid;
import com.hua.valid.AnnotationHandleFactory;
import com.hua.valid.ErrorMessage;
import com.hua.valid.HandleDTO;
import java.util.List;
public class Test {
public static void main(String[] args) {
Teach teach = init();
ErrorMessage errorMessage = new ErrorMessage();
if (!AnnotationHandleFactory.handle(new HandleDTO.HandleDTOBuilder()
.setOriginObj(teach)
.setAnnotations(teach.getListStu().get(0).getClass().getDeclaredFields()[0].getAnnotations())
.setField(teach.getListStu().get(0).getClass().getDeclaredFields()[0])
.setFieldValue(teach.getListStu().get(0).getName())
.setErrorMessage(errorMessage)
.build())) {
System.out.println("验证失败: " + errorMessage.getErrorMessage());
} else {
System.out.println("验证成功");
}
}
public static Teach init() {
Student student = new Student();
student.setName("张同学");
student.setAge(18);
student.setSex(1);
Student student1 = new Student();
student1.setName(null);
student1.setAge(19);
student1.setSex(2);
Teach teach = new Teach();
teach.setTeaAge(28);
teach.setTeaName("王老师");
teach.setTeaSex(1);
List<Student> student11 = List.of(student1, student);
teach.setListStu(student11);
return teach;
}
}

View File

@ -0,0 +1,147 @@
package com.hua.valid;
import cn.hutool.core.util.ArrayUtil;
import com.hua.annotation.Handles;
import com.hua.valid.annotation.PackageScanConfig;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.function.Consumer;
/**
* @author Hua
* @since 2024/7/18 下午2:43
*/
public class AnnotationHandleFactory {
// 缓存已加载的注解处理器
private static final Map<Class<? extends Annotation>, AnnotationHandler> cache = new HashMap<>();
private static boolean useSPI = true; // 是否使用SPI加载处理器
private static boolean useReflection = false; // 是否使用反射加载处理器
private static String[] packagesToScan = {"com.hua.valid"}; // 反射扫描的包路径
// 静态初始化块,在类加载时进行处理器初始化
static {
resolvePackageConfig();
initializeHandlers();
}
/**
* 配置处理器加载方式和扫描路径。
*
* @param useSpi 是否使用SPI加载处理器。
* @param useRef 是否使用反射加载处理器。
* @param packages 反射扫描的包路径。
*/
public static void configure(boolean useSpi, boolean useRef, String[] packages) {
useSPI = useSpi;
useReflection = useRef;
packagesToScan = packages;
cache.clear(); // 清除缓存
initializeHandlers(); // 重新初始化处理器
}
private static void resolvePackageConfig() {
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setUrls(ClasspathHelper.forJavaClassPath())
.setScanners(new TypeAnnotationsScanner(), new SubTypesScanner()));
// 查找所有应用了PackageScanConfig注解的类
Set<Class<?>> configClasses = reflections.getTypesAnnotatedWith(PackageScanConfig.class);
if (configClasses.isEmpty()) {
return;
}
PackageScanConfig config = configClasses.stream().findFirst().get().getAnnotation(PackageScanConfig.class);
useSPI = config.useSPI();
useReflection = config.useReflection();
packagesToScan = config.packages();
}
// 初始化处理器根据配置决定使用SPI或反射加载
private static void initializeHandlers() {
if (useSPI) {
loadHandlersViaSPI();
}
if (useReflection) {
loadHandlersViaReflection();
}
}
// 通过SPI加载注解处理器
private static void loadHandlersViaSPI() {
ServiceLoader<AnnotationHandler> loadedHandlers = ServiceLoader.load(AnnotationHandler.class);
loadedHandlers.forEach(handler -> {
Handles handles = handler.getClass().getAnnotation(Handles.class);
if (handles != null) {
cache.put(handles.value(), handler);
}
});
}
// 通过反射加载注解处理器
private static void loadHandlersViaReflection() {
// 单独的方法用于加载处理器
Consumer<Reflections> loadHandlers = (reflections) -> {
reflections.getTypesAnnotatedWith(Handles.class).forEach(cls -> {
try {
AnnotationHandler handler = (AnnotationHandler) cls.getDeclaredConstructor().newInstance();
Handles handlesAnnotation = cls.getAnnotation(Handles.class);
cache.put(handlesAnnotation.value(), handler);
} catch (ReflectiveOperationException e) {
// 推荐使用日志记录异常,而非仅仅打印堆栈信息
e.printStackTrace();
}
});
};
if (ArrayUtil.isEmpty(packagesToScan)) {
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setUrls(ClasspathHelper.forJavaClassPath())
.setScanners(new TypeAnnotationsScanner(), new SubTypesScanner()));
loadHandlers.accept(reflections);
} else {
for (String pkg : packagesToScan) {
Reflections reflections = new Reflections(new ConfigurationBuilder()
.forPackages(pkg)
.setScanners(new SubTypesScanner(), new TypeAnnotationsScanner()));
loadHandlers.accept(reflections);
}
}
}
/**
* 根据注解类型获取对应的处理器。
*
* @param annotation 注解实例。
* @return 对应的注解处理器如果未找到返回null。
*/
public static AnnotationHandler getHandler(Annotation annotation) {
return cache.get(annotation.annotationType());
}
/**
* 处理给定的注解数据对象。
*
* @param handleDTO 包含注解信息的数据传输对象。
* @return 处理结果,成功或失败。
*/
public static boolean handle(HandleDTO handleDTO) {
for (Annotation annotation : handleDTO.getAnnotations()) {
AnnotationHandler handler = getHandler(annotation);
if (handler != null) {
handleDTO.setCurrentAnnotation(annotation);
return handler.handle(handleDTO);
}
}
return true;
}
}

View File

@ -0,0 +1,5 @@
package com.hua.valid;
public interface AnnotationHandler {
boolean handle(HandleDTO handleDTO);
}

View File

@ -0,0 +1,32 @@
package com.hua.valid;
import cn.hutool.core.util.StrUtil;
import com.hua.annotation.Handles;
import com.hua.valid.annotation.ConditionNotNull;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
/**
* @author Hua
* @since 2024/7/18 下午2:43
*/
@Handles(ConditionNotNull.class)
public class ConditionNotNullHandler implements AnnotationHandler {
@Override
public boolean handle(HandleDTO handleDTO) {
ConditionNotNull conditionValidate = (ConditionNotNull) handleDTO.getCurrentAnnotation();
String test = conditionValidate.test();
if (StrUtil.isEmpty(test)) {
return true;
}
ExpressionParser parser = new SpelExpressionParser();
Boolean value = parser.parseExpression(test).getValue(handleDTO.getOriginObj(), Boolean.class);
if (Boolean.TRUE.equals(value) && handleDTO.getFieldValue() == null) {
handleDTO.getErrorMessage().addErrorObj(conditionValidate.message(), handleDTO.getField());
return false;
}
return true;
}
}

View File

@ -0,0 +1,69 @@
package com.hua.valid;
import cn.hutool.core.util.ReflectUtil;
import com.hua.valid.annotation.ValidPlus;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Valid;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;
/**
* @author Hua
* @since 2024/7/18 下午2:43
*/
public class ConditionValidateImpl implements ConstraintValidator<ValidPlus, Object> {
@Override
public void initialize(ValidPlus constraintAnnotation) {
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
ErrorMessage errorMessage = new ErrorMessage();
validObj(o, errorMessage, o);
if(errorMessage.isError()) {
constraintValidatorContext.disableDefaultConstraintViolation();
constraintValidatorContext.buildConstraintViolationWithTemplate(errorMessage.getErrorMessage()).addConstraintViolation();
return false;
}
return true;
}
private void validObj(Object o, ErrorMessage errorMessage, Object originObj) {
if (o instanceof List<?> list) {
for (Object obj : list) {
validObj(obj, errorMessage,originObj);
}
return;
}
Field[] fields = ReflectUtil.getFields(o.getClass());
for (Field field : fields) {
Valid annotation = field.getAnnotation(Valid.class);
if (annotation != null) {
validObj(ReflectUtil.getFieldValue(o,field),errorMessage, originObj);
}
Annotation[] annotations = field.getAnnotations();
if (annotations == null || annotations.length == 0) {
continue;
}
Object fieldValue = ReflectUtil.getFieldValue(o, field);
Annotation formatAnnotation = field.getAnnotation(ValidPlus.class);
if (formatAnnotation == null) {
throw new RuntimeException("Format annotation is missing on the field.");
}
HandleDTO handleDTO = new HandleDTO.HandleDTOBuilder().setOriginObj(originObj)
.setAnnotations(annotations)
.setAnnotations(annotations)
.setField(field)
.setErrorMessage(errorMessage)
.setFieldValue(fieldValue).build();
AnnotationHandleFactory.handle(handleDTO);
}
}
}

View File

@ -0,0 +1,57 @@
package com.hua.valid;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Hua
* @since 2024/7/18 下午2:43
*/
public class ErrorMessage {
private final List<ErrorObj> listErrorObj = new ArrayList<>();
public void addErrorObj(String errorMessage, Field errorField){
ErrorObj errorObj = new ErrorObj(errorMessage, errorField);
listErrorObj.add(errorObj);
}
public boolean isError() {
return listErrorObj.size() > 0;
}
public String getErrorMessage(){
return listErrorObj.stream().map(ErrorObj::getErrorMessage).collect(Collectors.joining(","));
}
public static class ErrorObj{
private String errorMessage;
private Field errorField;
public ErrorObj(String errorMessage, Field errorField) {
this.errorMessage = errorMessage;
this.errorField = errorField;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public Field getErrorField() {
return errorField;
}
public void setErrorField(Field errorField) {
this.errorField = errorField;
}
}
}

View File

@ -0,0 +1,128 @@
package com.hua.valid;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
/**
* @author Hua
* @since 2024/7/18 下午2:43
*/
public class HandleDTO {
/**
* 要验证的实体类的原始值(有可能 实体类里面嵌套实体的情况)
*/
private Object originObj;
/**
* 属性上加的所有的注解
*/
private Annotation[] annotations;
/**
* 当前要处理的注解
*/
private Annotation currentAnnotation;
/**
* 加注解的那个字段
*/
private Field field;
/**
* 错误信息
*/
private ErrorMessage errorMessage;
/**
* 加注解的那个字段值
*/
private Object fieldValue;
public Object getOriginObj() {
return originObj;
}
public void setOriginObj(Object originObj) {
this.originObj = originObj;
}
public Annotation[] getAnnotations() {
return annotations;
}
public void setAnnotations(Annotation[] annotations) {
this.annotations = annotations;
}
public Field getField() {
return field;
}
public void setField(Field field) {
this.field = field;
}
public ErrorMessage getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(ErrorMessage errorMessage) {
this.errorMessage = errorMessage;
}
public Object getFieldValue() {
return fieldValue;
}
public void setFieldValue(Object fieldValue) {
this.fieldValue = fieldValue;
}
public Annotation getCurrentAnnotation() {
return currentAnnotation;
}
public void setCurrentAnnotation(Annotation currentAnnotation) {
this.currentAnnotation = currentAnnotation;
}
public static class HandleDTOBuilder {
private final HandleDTO handleDTO;
public HandleDTOBuilder() {
handleDTO = new HandleDTO();
}
public HandleDTOBuilder setOriginObj(Object originObj) {
handleDTO.setOriginObj(originObj);
return this;
}
public HandleDTOBuilder setAnnotations(Annotation[] annotations) {
handleDTO.setAnnotations(annotations);
return this;
}
public HandleDTOBuilder setField(Field field) {
handleDTO.setField(field);
return this;
}
public HandleDTOBuilder setErrorMessage(ErrorMessage errorMessage) {
handleDTO.setErrorMessage(errorMessage);
return this;
}
public HandleDTOBuilder setFieldValue(Object fieldValue) {
handleDTO.setFieldValue(fieldValue);
return this;
}
public HandleDTOBuilder setCurrentAnnotation(Annotation currentAnnotation) {
handleDTO.setCurrentAnnotation(currentAnnotation);
return this;
}
public HandleDTO build() {
return handleDTO;
}
}
}

View File

@ -0,0 +1,16 @@
package com.hua.valid.annotation;
import java.lang.annotation.*;
/**
* @author Hua
* @since 2024/7/18 下午2:42
*/
@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ConditionNotNull {
String test() default "";
String message() default "";
}

View File

@ -0,0 +1,14 @@
package com.hua.valid.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE) // 类或接口上使用
@Retention(RetentionPolicy.RUNTIME) // 在运行时可见
public @interface PackageScanConfig {
boolean useSPI() default false; // 默认为空数组
boolean useReflection() default false; // 默认为空数组
String[] packages() default {}; // 默认为空数组
}

View File

@ -0,0 +1,21 @@
package com.hua.valid.annotation;
import com.hua.valid.ConditionValidateImpl;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* @author Hua
* @since 2024/7/18 下午2:43
*/
@Documented
@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ConditionValidateImpl.class)
public @interface ValidPlus {
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@ -0,0 +1 @@
com.hua.valid.ConditionNotNullHandler