spring-boot - 休眠方法验证并不总是有效
问题描述
为什么 Hibernate 的验证 - ConstraintViolationException - 没有在带有 spring-boot-starter-web 的 SpringBoot 应用程序(SpringBoot 的最新版本)的 main() 中抛出:
@Validated
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
someService.doStuff(new Item(null); // WHY NOT THROWN????????!!!!!!
// Expecting ConstraintViolationException: doStuff.item.content: must not be null
}}
// ----------------------
public class Item {
@NotNull
String content; // to be validated
//constructor, getter, setter
}
@Validated
@Service
public class SomeService {
void doStuff(@Valid Item item) {} // should break for Item's content = null
}
奇怪的是,在其他情况下,Hibernate 验证对相同的方法调用按预期工作:
- 当我将无效调用放入控制器的构造函数时,会引发 ConstraintViolationException :
public SomeController(SomeService someService){
this.someService = someService;
someService.doStuff(new Item(null); // throws ConstraintViolationException
}
- 同样如预期的那样,当我发出无效调用
in a constructor method
并在测试或 Postman 中调用端点时,会引发 ConstraintViolationException
@GetMapping("item")
public String item() {
someService.doStuff(new Item(null); // throws ConstraintViolationException
return "You never get here.";
}
解决方案
不知道你是如何获得someService
实例的Application
,但下面的代码对我有用(每个类都在不同的文件中):
@AllArgsConstructor
@Getter
@Setter
public class Item {
@NotNull
String content;
}
@Validated
@Service
public class SomeService {
public void doStuff(@Valid Item item) {
System.out.println(format("Item.content = %s", item.getContent()));
}
}
@SpringBootApplication
public class TestingPurposeApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(TestingPurposeApplication.class, args);
SomeService someService = context.getBean(SomeService.class);
someService.doStuff(new Item(null));
}
}
结果:
利用:
ConfigurableApplicationContext context = SpringApplication.run(MyApplication.class, args);
MyClass myInstance = context.getBean(MyClass.class);
是在方法中获取由 Spring 管理的组件的合适main
方法。
推荐阅读
- jquery - 格式化日期的jQuery语法
- java - 理解 Hybris 中的 Impex 语法语句
- google-sheets - 查询和导入范围只返回标题行
- arrays - Powershell读取文件夹下的文件名并读取每个文件内容以创建菜单项
- sql - SSIS 包,用于用游标替换存储过程,用连接子句替换不同的服务器
- text - Tkinter Text 小部件 tag_add 第二次不起作用
- google-cloud-platform - 谷歌语音中一些单词的问题
- macos - 如何阻止终端每次启动时访问 AVFoundationCF 框架?
- java - Firebase 数据库成本推送方法或反向数据树?
- r - 在列中找到最近的前一个负值