如何将相同的行为应用于扩展另一个 POJO 的 POJO

问题描述 投票:0回答:1

这更多的是一个理论问题而不是技术问题。我想知道实现某些方法(或方法?)以在扩展相同 POJO 的不同 POJO 上工作的最佳方法是什么。在我创建的示例应用程序中,我想使用 jakarta 验证一些 POJO(Jakarta Bean Validation)。 在这里您可以找到完整的示例应用程序zoo repo,无论如何我将在这里描述主要功能。

我专注于 SpringBoot 应用程序。

我有一个休息控制器,接受列表作为输入:


@RestController
@RequestMapping(value = "/api/v1", produces = MediaType.APPLICATION_JSON_VALUE)
public class AnimalController {

        AnimalService service;
        
        @PostMapping("/validate")
        @ResponseStatus(value = HttpStatus.OK)
        public List<ValidationErrorDTO>  validateCollection(@RequestBody List<AnimalDTO> request)
                                                        {
            return service.validateCollection(request);
        }
        
        
        public AnimalController(AnimalService service) {
            super();
            this.service = service;
        }
        
        
}

在 AnimalDTO 类中,我在属性上添加了一些 jakarta 注释:

import jakarta.validation.constraints.Size;

public class AnimalDTO {

    
    @Size(max = 5, message = "name can not be longer than 5")
    private String name;
    @Size(max = 5, message = "owner can not be longer than 5")
    private String owner; 
    
...

在服务的方法实现中我收到错误:

@Component
public class AnimalServiceImpl implements AnimalService{

    
    
    @Override
    public List<ValidationErrorDTO> validateCollection(List<AnimalDTO> collection) {
        
        List<ValidationErrorDTO> validationErrorList = new ArrayList<>();
        //instantiate the validator
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        
        //for every record of the collection, validate the record and add errors to the error list
        for(int i= 0; i<collection.size();i++) {

            int k =i;
            //get single record errors
            Set<ConstraintViolation<AnimalDTO>> violations = validator.validate(collection.get(i));

            violations.forEach(v -> validationErrorList.add(new ValidationErrorDTO(k, v.getPropertyPath().toString(), v.getMessage())));
        }
        
        return validationErrorList;
    }

}

现在,我有两个 POJO DogDTO 和 CatDTO 扩展了 AnimalDTO,我想重用相同的方法,或者无论如何在这种情况下应用最佳模式来验证输入列表。

我有什么选择?

我没有尝试任何编码,因为这不是技术问题,但我确信我错过了一些东西。也许我想太多了,最好的方法就是使用另一种方法?

java spring-boot validation design-patterns bean-validation
1个回答
0
投票

在 spring-boot 中使用 bean 验证的正确方法是使用

@Validated
注释 bean。然后它将创建一个 AOP 代理,该代理包装此 bean 中的任何方法,其中输入或输出参数都使用 bean 验证注释进行注释。代理将在执行这些方法之前和之后调用
Validator
来验证输入/输出参数,因此您不需要自己执行此操作。

如果输入参数验证失败,该方法将不会执行并抛出

ConstraintViolationException
,内部包含所有
ConstraintViolation

就代码而言,它看起来像:

@Validated
public class AnimalServiceImpl implements AnimalService{

    @Override
    public void validate(List<@Valid AnimalDTO> collection) {
        ......
    }

}

调用者需要捕捉

ConstraintViolationException
并将其转换为
List<ValidationErrorDTO>
喜欢 :

List<AnimalDTO> animals = new ArrayList<>();
animals.add(cat1Dto);
animals.add(cat2Dto);
animals.add(dog1Dto);
animals.add(dog2Dto);

try{
    animalService.validate(animals);
} catch (ConstraintViolationException exp) {
    Set<ConstraintViolation<?>> violations = exp.getConstraintViolations();
    //convert them to List<ValidationErrorDTO>
    //you can create a helper method for code reuse if necessary
}
© www.soinside.com 2019 - 2024. All rights reserved.