如何以编程方式使用 Spring Validator 验证 Map<String, String>
How to validate a Map<String, String> using Spring Validator programmatically
我有一个地图,我从第三方的浏览器重定向回我的 Spring 控制器,如下所示 -
@RequestMapping(value = "/capture", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void capture(@RequestParam
final Map<String, String> response)
{
// TODO : perform validations first.
captureResponse(response);
}
在使用此负载之前,我需要进行重要的验证,包括首先检查映射的非空值,然后在校验和验证中使用这些值。因此,我想使用 Spring Validator 接口以编程方式验证我的有效载荷。但是,我找不到任何用于验证 Map 的验证器示例。
为了验证 Java 对象,我了解如何通过传递对象和 BeanPropertyBindingResult 来调用验证器以将错误包含到验证器,如下所示 -
final Errors errors = new BeanPropertyBindingResult(object, objectName);
myValidator.validate(object, errors);
if (errors.hasErrors())
{
throw new MyWebserviceValidationException(errors);
}
对于地图,我可以看到 MapBindingResult
class 延伸 AbstractBindingResult
。我应该简单地使用它,并在 Object object
中传递我的地图,然后在验证器中将其转换回 Map
吗?另外,supports(final Class<?> clazz)
的 Validator 方法将如何在我的验证器中实现?它会像下面的代码片段一样,只能有一个验证器支持 HashMap 的这个通用 class 吗?怎么感觉不太对。 (虽然这对我来说并不重要,因为我将注入我的验证器并直接使用它,而不是通过验证器注册表,但仍然很好奇。)
@Override
public boolean supports(final Class<?> clazz)
{
return HashMap.class.equals(clazz);
}
因为有一个 MapBindingResult,我肯定 Spring 必须支持地图进行验证,想知道如何。所以想知道这是不是要走的路,还是我走错了方向,还有更好的方法。
请注意,我想以编程方式而不是通过注释来执行此操作。
另一种方法是为地图创建自定义约束注释。
你可以看看下面的link:
正如我所想,Spring Validator org.springframework.validation.Validator
确实支持对 Map 的验证。我自己试了一下,确实有效!
我通过传入我需要验证的地图和该地图的标识符名称(用于 global/root-level 错误消息)创建了一个 org.springframework.validation.MapBindingResult
。这个 Errors 对象在验证器中传递,连同要验证的地图一起传递,如下面的代码片段所示。
final Errors errors = new MapBindingResult(responseMap, "responseMap");
myValidator.validate(responseMap, errors);
if (errors.hasErrors())
{
throw new MyWebserviceValidationException(errors);
}
MapBindingResult
扩展了 AbstractBindingResult
并覆盖了方法 getActualFieldValue
以提供它自己的实现以从正在验证的地图中获取字段。
private final Map<?, ?> target;
@Override
protected Object getActualFieldValue(String field) {
return this.target.get(field);
}
因此,在验证器中,我能够使用 org.springframework.validation.ValidationUtils
中提供的所有有用的实用方法,就像我们在标准对象 bean 验证器中使用的那样。例如 -
ValidationUtils.rejectIfEmpty(errors, "checksum", "field.required");
其中 "checksum" 是我地图中的一个键。啊,传承之美! :)
对于其他 non-trivial 验证,我只是将 Object 转换为 Map 并编写了我的自定义验证代码。
所以验证器看起来像 -
@Override
public boolean supports(final Class<?> clazz)
{
return HashMap.class.equals(clazz);
}
@Override
public void validate(final Object target, final Errors errors)
{
ValidationUtils.rejectIfEmpty(errors, "transactionId", "field.required");
ValidationUtils.rejectIfEmpty(errors, "checksum", "field.required");
final Map<String, String> response = (HashMap<String, String>) target;
// do custom validations with the map's attributes
// ....
// if validation fails, reject the whole map -
errors.reject("response.map.invalid");
}
验证地图中的参数
为了按照特定映射验证您的地图,您将需要一个自定义验证器。
因为这可能是某些人的用例,所以可以使用 org.springframework.validation
注释来完成 @RequestParam
的验证,例如
@GetMapping(value = "/search")
public ResponseEntity<T> search(@RequestParam
Map<@NotBlank String,@NotBlank String> searchParams,
虽然 @NotBlank
检查您的字符串是否不是 ""
,
@NotNull
可以验证 non-null 个参数,我猜这是你需要的。
我有一个地图,我从第三方的浏览器重定向回我的 Spring 控制器,如下所示 -
@RequestMapping(value = "/capture", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void capture(@RequestParam
final Map<String, String> response)
{
// TODO : perform validations first.
captureResponse(response);
}
在使用此负载之前,我需要进行重要的验证,包括首先检查映射的非空值,然后在校验和验证中使用这些值。因此,我想使用 Spring Validator 接口以编程方式验证我的有效载荷。但是,我找不到任何用于验证 Map 的验证器示例。
为了验证 Java 对象,我了解如何通过传递对象和 BeanPropertyBindingResult 来调用验证器以将错误包含到验证器,如下所示 -
final Errors errors = new BeanPropertyBindingResult(object, objectName);
myValidator.validate(object, errors);
if (errors.hasErrors())
{
throw new MyWebserviceValidationException(errors);
}
对于地图,我可以看到 MapBindingResult
class 延伸 AbstractBindingResult
。我应该简单地使用它,并在 Object object
中传递我的地图,然后在验证器中将其转换回 Map
吗?另外,supports(final Class<?> clazz)
的 Validator 方法将如何在我的验证器中实现?它会像下面的代码片段一样,只能有一个验证器支持 HashMap 的这个通用 class 吗?怎么感觉不太对。 (虽然这对我来说并不重要,因为我将注入我的验证器并直接使用它,而不是通过验证器注册表,但仍然很好奇。)
@Override
public boolean supports(final Class<?> clazz)
{
return HashMap.class.equals(clazz);
}
因为有一个 MapBindingResult,我肯定 Spring 必须支持地图进行验证,想知道如何。所以想知道这是不是要走的路,还是我走错了方向,还有更好的方法。
请注意,我想以编程方式而不是通过注释来执行此操作。
另一种方法是为地图创建自定义约束注释。
你可以看看下面的link:
正如我所想,Spring Validator org.springframework.validation.Validator
确实支持对 Map 的验证。我自己试了一下,确实有效!
我通过传入我需要验证的地图和该地图的标识符名称(用于 global/root-level 错误消息)创建了一个 org.springframework.validation.MapBindingResult
。这个 Errors 对象在验证器中传递,连同要验证的地图一起传递,如下面的代码片段所示。
final Errors errors = new MapBindingResult(responseMap, "responseMap");
myValidator.validate(responseMap, errors);
if (errors.hasErrors())
{
throw new MyWebserviceValidationException(errors);
}
MapBindingResult
扩展了 AbstractBindingResult
并覆盖了方法 getActualFieldValue
以提供它自己的实现以从正在验证的地图中获取字段。
private final Map<?, ?> target;
@Override
protected Object getActualFieldValue(String field) {
return this.target.get(field);
}
因此,在验证器中,我能够使用 org.springframework.validation.ValidationUtils
中提供的所有有用的实用方法,就像我们在标准对象 bean 验证器中使用的那样。例如 -
ValidationUtils.rejectIfEmpty(errors, "checksum", "field.required");
其中 "checksum" 是我地图中的一个键。啊,传承之美! :)
对于其他 non-trivial 验证,我只是将 Object 转换为 Map 并编写了我的自定义验证代码。
所以验证器看起来像 -
@Override
public boolean supports(final Class<?> clazz)
{
return HashMap.class.equals(clazz);
}
@Override
public void validate(final Object target, final Errors errors)
{
ValidationUtils.rejectIfEmpty(errors, "transactionId", "field.required");
ValidationUtils.rejectIfEmpty(errors, "checksum", "field.required");
final Map<String, String> response = (HashMap<String, String>) target;
// do custom validations with the map's attributes
// ....
// if validation fails, reject the whole map -
errors.reject("response.map.invalid");
}
验证地图中的参数
为了按照特定映射验证您的地图,您将需要一个自定义验证器。
因为这可能是某些人的用例,所以可以使用 org.springframework.validation
注释来完成 @RequestParam
的验证,例如
@GetMapping(value = "/search")
public ResponseEntity<T> search(@RequestParam
Map<@NotBlank String,@NotBlank String> searchParams,
虽然 @NotBlank
检查您的字符串是否不是 ""
,
@NotNull
可以验证 non-null 个参数,我猜这是你需要的。