【问题标题】:Validation does not execute in service layer验证不在服务层执行
【发布时间】:2019-09-07 18:02:32
【问题描述】:

hibernate-validator 在我的 Spring Boot 项目的服务层中不起作用。

我的领域模型:

@Data
public class IssueAttachmentDto extends AttachmentDto {

    @NotEmpty
    private String issueId;

}

@Data
public class AttachmentDto {

    /**
     * Only allow digit 1~5
     */
    @NotEmpty
    @Pattern(regexp = "\\b[1-5]\\b")
    private String attachmentType;

    @NotEmpty
    @Valid
    private FileDto fileDto;
}

@Data
public class FileDto extends BaseDto {

    @NotEmpty
    private String fileType;

    /**
     * Only allow positive integer
     */
    @NotEmpty
    @Pattern(regexp = "^[0-9]*[1-9][0-9]*$")
    private Long fileSize;

    @NotEmpty
    private String fileKey;

    @NotEmpty
    private String fileName;
}

我的服务等级:


@Slf4j
@Service
@Validated
public class AttachmentServiceImpl implements AttachmentService { 
  @Override
  public void uploadAttachment(IssueAttachmentDto issueAttachmentDto) {
    try {
      checkUploadAttachmentArgument(issueAttachmentDto);
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
        // something else...
  }

  private void checkUploadAttachmentArgument(@Valid IssueAttachmentDto issueAttachmentDto) {
    // something else
  }
}

我的配置类:

@Configuration
public class ConversionConfig {

    @Bean
    public ConversionService conversionService() {
        return new DefaultConversionService();
    }
}

无论我通过什么方法checkUploadAttachmentArgument(@Valid IssueAttachmentDto issueAttachmentDto) 都不会抛出异常。在我的假设中,当我传递非法数据时,它会抛出一个 ConstraintViolationException 。我的代码或配置有什么问题,请帮助我。

【问题讨论】:

  • 首先您可以删除@Validated 注释,该注释无用,它用于验证组。你的类路径中是否有 Hibernate 验证器或任何其他验证器?
  • @ThomasAndolf 是的,我确信我的验证器在我的类路径中。如果不是这样,我该如何编译上面的代码?
  • 您可以编译代码,因为您使用的是 spring 注释和 JSR-303 特定的注释。您可以毫无问题地使用这些注释,而无需在类路径上进行任何底层验证实现,因为这些只是规范注释。它们不是实际的实现。既然你还没有发布你的 pom.xml 我不得不清除它。
  • 感谢您的信赖。最后,我通过手动新建一个验证器解决了我的问题,并使用这个验证器来验证我的 bean。

标签: java spring-boot hibernate-validator


【解决方案1】:

Spring 不能代理私有方法——这就是为什么当无效对象作为参数传递时你看不到任何异常被抛出。

只需将 @Valid 注释移动到 uploadAttachment 方法参数,它应该可以按预期工作。它应该是这样的:

public void uploadAttachment(@Valid IssueAttachmentDto issueAttachmentDto) {
    // actual upload attachent logic
}

编辑:

即使 Spring 可以代理私有方法,它也不会在您的情况下验证带注释的参数,因为您实际上在原始类的实例上调用 checkUploadAttachmentArgument 而不是额外执行验证的代理。

【讨论】:

  • 首先感谢您的回答。但是在我将checkUploadAttachmentArgument(@Valid IssueAttachmentDto issueAttachmentDto) 更改为这样之后,我仍然无法捕捉到任何异常:public void checkUploadAttachmentArgument(@Valid IssueAttachmentDto issueAttachmentDto) { }
  • 是的,你不会发现任何异常 - 我已经更新了我的答案并解释了原因。您根本不需要checkUploadAttachmentArgument 方法,只需像上面的示例一样修改uploadAttachment 方法。
  • 当我通过attachmentType = 8时,按照你的例子,我仍然没有得到任何异常。
  • 你如何测试它?
  • IssueAttachment foo = new IssueAttachmentDto(); foo.setAttachmentType("8"); attachentService.uploadAttachment(foo)
猜你喜欢
  • 2012-01-19
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 2013-05-23
  • 1970-01-01
  • 2015-11-22
相关资源
最近更新 更多