简体   繁体   中英

How to intercept method before invoke and check param?

How to intercept method with before invoked and check param?

I add custom annotations Dto, DtoFiels and write it on RestController and method createEntity. How to check all fields annotated in object annotated DtoFiels. I try add BeanPostProcessor and invoke with Proxy.newProxyInstance with InvocationHandler, but it throw ExceptionHandlerExceptionResolver - Resolved exception caused by Handler execution: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction ExceptionHandlerExceptionResolver - Resolved exception caused by Handler execution: org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction

I try add ConstraintValidator with my annotation and annotate @Valid, but it check all fields with annotate @NotNull and @CreatedDate.

method

 @PostMapping @Dto
 public CompletableFuture<Response> createEntity(@RequestBody Entity entity) {

Class Entity:

@Column(nullable = false)
protected String name;

protected String description;

@Column(nullable = false, updatable = false)
@CreatedDate
protected LocalDateTime creationDate;

@NotNull
protected boolean deleted;

@NotNull
@LastModifiedDate
protected LocalDateTime modificationDate;

You can use validation groups to define which constraints should be validated and which ones should not be validated. I'm assuming that when createEntity is invoked, you don't want the @NotNull and other validations to be enforced. Instead, you want some other custom validation code to be executed...

Define your validations in a class level constraint .

@Data
public class Person {

    @NotEmpty
    @Size(min = 10)
    @Pattern(regexp = "[0-9]*")
    private String name;
}

Custom class level constraint

@Target({ ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = { PersonValidator.class })
@Documented
public @interface ValidPerson {

    String message() default "Invalid person";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

Validator for the custom constraint defined above which only checks that the name is not null. Size and regex validations are not applied.

public class PersonValidator implements ConstraintValidator<ValidPerson, Person> {
    @Override
    public boolean isValid(Person person, ConstraintValidatorContext context) {
        // Add your validation code here
        if (person == null) {
            return true;
        }
        return person.getName() != null;
    }
}

Create a custom group and validate your parameter using this group. As your regular validations are not part of this group, those constraints will not be validated.

public interface CustomPersonGroup {

}

@Service
@Validated
public class SomeService {

    public void test(@Validated(value = CustomPersonGroup.class) @ValidPerson Person person) {

    }
}

If the validations that you want to perform can be expressed in terms of the standard bean validation annotations, you can do the following.

@Data
public class Person {

    @NotEmpty(groups = CustomPersonGroup.class)
    @Size(min = 10)
    @Pattern(regexp = "[0-9]*")
    private String name;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM