Я пытаюсь создать динамический класс, используя Bytebuddy с проверкой, встроенной, чтобы я мог проверить все необходимые входы/и т. Д. Метод проверки проходит, и если я проверю valyator.getConstraintSforClass (DynamicClass) < /code>, ограничений не найдено.plugins {
id 'java'
id 'io.quarkus'
id 'io.freefair.lombok' version '8.12'
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-rest'
implementation 'io.quarkus:quarkus-arc'
implementation 'io.quarkus:quarkus-rest-jackson'
implementation 'io.quarkus:quarkus-rest-client-jackson'
implementation 'io.quarkus:quarkus-hibernate-validator'
implementation 'net.bytebuddy:byte-buddy:1.14'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
}
group 'org.acme'
version '1.0.0-SNAPSHOT'
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
test {
systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager"
}
compileJava {
options.encoding = 'UTF-8'
options.compilerArgs
классы Java < /li>
< /ol>
package org.acme;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.dynamic.DynamicType;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@Slf4j
public class DynamicPojoFactory {
private DynamicPojoFactory() {}
public static Builder builder() {
return new Builder();
}
private static String buildName() {
return "DynamicClass_"
+ UUID.randomUUID().toString().replace("-", "");
}
public static class Builder {
private final Set definitions = new HashSet();
public Builder addField(
final String fieldName,
final Class type,
final AnnotationDescription annotation) {
final FieldDefinition definition =
new FieldDefinition(fieldName, type, Set.of(annotation));
return addField(definition);
}
public Builder addField(final FieldDefinition fieldDefinition) {
definitions.add(fieldDefinition);
return this;
}
public Class build() {
DynamicType.Builder builder =
new ByteBuddy().subclass(Object.class).name(buildName());
for (FieldDefinition fieldDefinition : definitions) {
builder =
builder.defineProperty(fieldDefinition.name(), fieldDefinition.type())
.annotateField(fieldDefinition.annotations().stream().toList());
}
return builder.make().load(this.getClass().getClassLoader()).getLoaded();
}
}
}
< /code>
package org.acme;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.Accessors;
import net.bytebuddy.description.annotation.AnnotationDescription;
import java.util.Set;
@Getter
@AllArgsConstructor
@Accessors(fluent = true)
public class FieldDefinition {
private String name;
private Class type;
private Set annotations;
}
< /code>
package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validator;
import jakarta.validation.constraints.NotEmpty;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.description.annotation.AnnotationDescription;
import java.util.List;
import java.util.Set;
@Slf4j
@Path("/test")
@ApplicationScoped
@RequiredArgsConstructor
public class TestResource {
@Inject
Validator validator;
@SneakyThrows
@GET
@Path("")
@Produces(MediaType.APPLICATION_JSON)
public Object test() {
List fields =
List.of(
new FieldDefinition(
"firstName",
String.class,
Set.of(AnnotationDescription.Builder.ofType(NotEmpty.class).build())),
new FieldDefinition(
"lastName",
String.class,
Set.of(AnnotationDescription.Builder.ofType(NotEmpty.class).build())));
final DynamicPojoFactory.Builder dynamicClassBuilder = DynamicPojoFactory.builder();
fields.forEach(dynamicClassBuilder::addField);
Class dynamicClass = dynamicClassBuilder.build();
logAnnotations(dynamicClass);
Object person = dynamicClass.getDeclaredConstructor().newInstance();
dynamicClass.getMethod("setFirstName", String.class).invoke(person, "Bill");
// dynamicClass.getMethod("setLastName", String.class).invoke(person, "Nye"); // attempt to cause validation failure by not setting last name
Set violations = validator.validate(person); // TODO: why does this pass??
if (!violations.isEmpty()) {
for (var violation : violations) {
System.out.println("Validation Error: " + violation.getMessage());
}
} else {
System.out.println("Validation passed.");
}
return person;
}
private void logAnnotations(Class dynamicClass) {
log.info("logging annotations.");
log.info("found {} methods", dynamicClass.getMethods().length);
// Get all the methods from the dynamic class (which include getters and setters)
for (Method method : dynamicClass.getMethods()) {
// Check for getter methods that are expected to have annotations
if (method.getName().startsWith("get") || method.getName().startsWith("set")) {
// Log method annotations
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
log.info("Method {} has annotation: {}", method.getName(), annotation);
}
}
}
log.info("found {} fields", dynamicClass.getDeclaredFields().length);
// You can also check field annotations
for (Field field : dynamicClass.getDeclaredFields()) {
// Log field annotations
Annotation[] fieldAnnotations = field.getAnnotations();
for (Annotation annotation : fieldAnnotations) {
log.info("Field {} has annotation: {}", field.getName(), annotation);
}
}
}
}
< /code>
Run quarkusDev and hit the /test endpoint or set up a simple test class. Console logs show that validation passes.
Подробнее здесь: https://stackoverflow.com/questions/795 ... validation