我有
一个实体:
package org.ibp.soq;
public class MyEntity {
private String field1;
private String field2;
//..getters and setters
}
实体的验证器:
package org.ibp.soq;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
@Component
public class MyEntityValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return MyEntity.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
MyEntity myEntity = (MyEntity) target;
// Logic to validate my entity
System.out.print(myEntity);
}
}
和
采用批量PUT方法的REST控制器:
package org.ibp.soq;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/myEntity")
public class MyEntityRestResource {
@Autowired
private MyEntityValidator myEntityValidator;
@InitBinder
protected void initBinder(final WebDataBinder binder) {
binder.addValidators(this.myEntityValidator);
}
@RequestMapping(method = RequestMethod.PUT)
public void bulkCreate(@RequestBody @Valid List<MyEntity> myEntities) {
// Logic to bulk create entities here.
System.out.print(myEntities);
}
}
当我使用以下请求正文对此资源发出PUT请求时:
[
{
"field1": "AA",
"field2": "11"
},
{
"field1": "BB",
"field2": "22"
}
]
我得到的错误是:
"Invalid target for Validator [org.ibp.soq.MyEntityValidator@4eab617e]: [org.ibp.soq.MyEntity@21cebf1c, org.ibp.soq.MyEntity@c64d89b]"
我可以理解,这是因为MyEntityValidator“支持”单个MyEntity验证,而不是对ArrayList的验证
如果在请求正文中有一个MyEntity对象和一个带有有效MyEntity MyEntity参数的相应控制器方法,则MyEntityValidator可以完美地工作。
如何扩展我使用的验证器设置,以支持MyEntity集合的验证?
实际上,这可以通过使用Spring验证和JSR303来实现。
正如您可能已经猜到的,使用Spring验证无法实现这一点。Spring验证实现Bean验证(JSR303/349),而不是对象验证。不幸的是,集合不是Java Bean。你有两个选择
myEntityValidator中手动调用验证器。验证(目标对象,错误)
。解决方案是为集合
创建一个自定义的验证器
,以及一个@ControllerAdvice
在WebDataBinder
中注册该验证器。
验证器:
import java.util.Collection;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
/**
* Spring {@link Validator} that iterates over the elements of a
* {@link Collection} and run the validation process for each of them
* individually.
*
* @author DISID CORPORATION S.L. (www.disid.com)
*/
public class CollectionValidator implements Validator {
private final Validator validator;
public CollectionValidator(LocalValidatorFactoryBean validatorFactory) {
this.validator = validatorFactory;
}
@Override
public boolean supports(Class<?> clazz) {
return Collection.class.isAssignableFrom(clazz);
}
/**
* Validate each element inside the supplied {@link Collection}.
*
* The supplied errors instance is used to report the validation errors.
*
* @param target the collection that is to be validated
* @param errors contextual state about the validation process
*/
@Override
@SuppressWarnings("rawtypes")
public void validate(Object target, Errors errors) {
Collection collection = (Collection) target;
for (Object object : collection) {
ValidationUtils.invokeValidator(validator, object, errors);
}
}
}
控制器建议:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
/**
* Controller advice that adds the {@link CollectionValidator} to the
* {@link WebDataBinder}.
*
* @author DISID CORPORATION S.L. (www.disid.com)
*/
@ControllerAdvice
public class ValidatorAdvice {
@Autowired
protected LocalValidatorFactoryBean validator;
/**
* Adds the {@link CollectionValidator} to the supplied
* {@link WebDataBinder}
*
* @param binder web data binder.
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.addValidators(new CollectionValidator(validator));
}
}
我为我的模型定制了一个 : 我希望当在请求中传递无效值时,HTTP400错误请求将自动返回。然而,这种情况并不发生。如果存在任何绑定错误,应该怎样做才能使Web API返回HTTP400?
问题内容: 在Spring MVC中,将请求 参数 绑定到处理请求的方法参数很容易。我只是用。但是我可以对request 属性 做同样的事情吗?当前,当我想访问request 属性时 ,我必须执行以下操作: 但是我真的很想使用这样的东西: 不幸的是,这种方式行不通。我可以以某种方式扩展Spring功能并添加自己的“绑定器”吗? 编辑 (我要实现的目标) :我将当前登录的用户存储在request属性
但是使用此代码会出现冲突,因为我已经用FXML代码定义了项目中的控制器,要解决这一问题,删除FXML代码中的段就足够了,但是我不会这么做,因为将代码留在FXML中允许我访问SceneBuilder的一些好特性。
我有一个绑定到< code >列表的wpf组合框 如果我的数据源是自定义集合,那么绑定很容易,我应该只从自定义集合传递属性名称,但由于绑定源是字符串列表,绑定属性应该是什么?
我最近在读Java中的思维(第四版)时,遇到了一个关于Java中方法绑定的问题。首先让我们看看书中的两个定义: 将方法调用连接到方法体称为绑定。 Java中的所有方法绑定都使用后期绑定,除非方法是静态的或最终的。 您可以在多态性章节的方法调用绑定一节中找到这些定义。(第281-282页) null
相信 Python 程序员多多少少都和我一样遇到过 Method Unbound Error,直译过来就是 “方法未绑定错误”,虽然搜索之后知道了使用 @classmethod 这样的装饰起后就可以解决问题, 但是一直没有得到完全解惑。 我们知道,Python 是一个动态语言,在类的创建过程中甚至实例化以后都能动态地修改其方法、 属性,这种做法通常被称为“Monkey Patching”,虽然我们