虽然,这个问题已经得到了回答,但我很感兴趣为什么@验证
需要用于Map的工作级联验证
更新2:为了更深入地理解,我找到了这些帖子(一、二和三),其中解释了
@Validated
需要激活方法级验证。借助于此,集合可以被验证,因为它们不是经过验证的JavaBean(JSR 303)。
解决方案:我已经用工作代码示例更新了我的代码片段和我的存储库。我所要做的就是用
@Valated
注释我的控制器,并在员工
中添加一些getter。Method odValidationPostProcess
根本不需要。
更新:我更新了我的问题和分叉的Spring Boot Rest示例,以添加一个最小的Rest API来演示:
Github回购。示例值在自述文件中。md!
我有一个Spring Boot 2 API来存储一些员工。我可以传递一个员工或映射
@Validated //this is the solution to activate map validation
@RestController
class EmployeeController {
@PostMapping("/employees")
List<Employee> newEmployee(@RequestBody @Valid Employee newEmployee) {
...
}
@PostMapping("/employees/bulk")
List<Employee> newEmployee(@RequestBody Map<String, @Valid Employee>
newEmployees) {
...
}
}
雇员存在一些内部静态类,也需要验证:
public class Employee {
@NotBlank
public final String name;
@Valid
public final EmployeeRole role;
@JsonCreator
public Employee(@JsonProperty("name") String name,
@JsonProperty("role") EmployeeRole role) {
this.name = name;
this.role = role;
}
// getters
public static class EmployeeRole {
@NotBlank
public String rolename;
@Min(0)
public int rating;
@JsonCreator
public EmployeeRole(@JsonProperty("rolename") String rolename,
@JsonProperty("rating") int rating) {
this.rolename = rolename;
this.rating = rating;
}
// getters
}
}
目前,单个请求的验证正在工作,但不适用于我的批量请求。据我所知,这应该可以通过Bean验证2.0实现。
你知道我做错了什么吗?我需要编写自定义验证器吗?
在spring系统中有两种验证。
我们可以看到A更窄,而B更常见。我想从两个方面回答这个问题。
正如这篇文章中描述的,更详细的
部分,A和B通过调用org.hibernate.validator.internal.engine.ValidatorImpl
中的不同方法通过aop触发方法增强,这导致了差异。
它们是不同的方法,具有不同的功能,因此会导致不同的结果。你可以通过阅读这两种方法找到答案。
JSR-303定义了我们上面讨论的方法的函数。
验证方法部分解释了验证方法,实现必须遵守验证例程中定义的逻辑,其中它声明将对对象的所有可达字段执行所有约束验证,这就是为什么List
对象(或其他集合实例)的元素无法通过此方法进行验证-集合的元素不是集合实例的字段。
但是,JSR-303实际上并没有将其作为主要主题,并将其放在附录C中。方法级验证建议。它提供了一些描述:
The constraints declarations evaluated are the constraints hosted on the parameters of the method or constructor. If @Valid is placed on a parameter, constraints declared on the object itself are considered.
validateReturnedValue evaluates the constraints hosted on the method itself. If @Valid is placed on the method, the constraints declared on the object itself are considered.
public @NotNull String saveItem(@Valid @NotNull Item item, @Max(23) BigDecimal price)
In the previous example,
- item is validated against @NotNull and all the constraints it hosts
- price is validated against @Max(23)
- the result of saveItem is validated against @NotNull
并惊叹Bean验证提供者可以自由地将此方案作为特定的扩展来实现。据我所知,Hibernate验证项目实现了这个方法,使约束作用于对象本身和集合对象的元素。
我不知道为什么Spring框架的家伙会在Request est响应体方法处理器
中调用validateParamete
,使得stackoverflow中出现了很多相关的问题。也许只是因为超文本传输协议post body数据通常是表单数据,自然可以用java bean来表示。如果是我,我会在Request est响应体方法处理器
中调用validateParamete
以方便使用。
要使其正常工作,您必须执行以下操作:
将MethodValidationPostProcessor添加到配置中
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
将已验证的添加到您的员工控制器
@Validated
@RestController
public class EmployeeController {}'
将有效的添加到地图或员工
public List<Employee> newEmployee(@RequestBody @Valid Map<String, Employee> newEmployees) {}
public List<Employee> newEmployee(@RequestBody Map<String, @Valid Employee> newEmployees) {}
这就是全部。这是完整的员工控制器:
@Validated
@RestController
public class EmployeeController {
@PostMapping("/employees")
public List<Employee> newEmployee(@RequestBody @Valid Employee newEmployee) {
return Collections.singletonList(newEmployee);
}
@PostMapping("/employees/bulk")
public List<Employee> newEmployee(@RequestBody @Valid Map<String, Employee> newEmployees) {
return new ArrayList<>(newEmployees.values());
}
}
和SpringBoot配置文件
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
}
希望对你有帮助。
我创建映射如下所示。如何将平面dto对象属性(街道、城市等)映射到域对象中的嵌套地址。当我试着去做的时候,我发现了一个错误: [错误]诊断:返回类型中的属性“Address.PostalCode”未知。@Mapping(来源=“City”,目标=“Address.City”), 还有类...
我试图通过将请求参数直接绑定到用户实体来简化我的代码,而不是一个字段一个字段地复制值,但是我似乎不能通过这种方式得到验证。 控制器: 验证器: 模型(注意嵌套对象用@Valid标注): 问题是只有密码和重新密码字段被正确验证,用户类中的验证注释被忽略,任何密码匹配的请求都通过,但它应该会出现错误。空密码或不同的密码会按预期出现错误。
我的问题是如何将对象包含嵌套对象映射到DTO,而不是嵌套对象的值,例如,如果有2个这样的类: 调用TestClassDTOToTestClass()并发送TestClassDTO包含NestedClassDTO.之后。。返回的TestClass为空NestedClass。。有没有可能不用自己编写地图绘制程序来绘制地图? 嘘
我试图动态解析一些JSON到一个Map 但是当我尝试使用一些更复杂的JSON和嵌套信息时失败了。我试图从json解析示例数据。组织 我得到以下错误 异常在线程"main"com.fasterxml.jackson.databind.JsonMapping异常:不能反序列化实例的java.lang.字符串START_OBJECT令牌 有没有办法将复杂的JSON数据解析成映射?
我不确定如何将嵌套的结果集映射到域实体中。 以下是我想做的事情的大概想法: 2张桌子 域实体(包含嵌套列表) LoanEntity.java Book.java 持久实体 Loans.java Dao.xml(不知道如何映射它,尝试使用一个) 注意:此查询将复制找到的#本书的记录。 LoanMapper.java 下面的错误是我得到的: 错误:结果类型中的未知属性“books.bookName”c
我如何在下面的场景中使用Mapstruct进行bean映射。 现在我想把sourceId映射到targetId,courseName映射到subjectName,studentName映射到memberName(list到list)。