我是Spring的新手,我正在使用一个接收国家/地区字符串作为标头的API。我想使用@Valid注释来验证该字符串是我们支持的国家之一。
当前,我们正在使用HandlerInterceptorAdapter进行此操作,但我们想更改此方法以提高性能。有没有一种优雅的方法可以在控制器中验证此标头?
更具体地说,验证需要获取配置的属性列表,并检查标头国家/地区是否在列表中。
例如这样的东西:
@PutMapping(path = "/endpoint", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.ACCEPTED)
public ResponseEntity<Void> createObject(@RequestBody @Valid final MyRequest myRequest,
@ApiParam(value = ApiConstants.COUNTRY_HEADER, required = true) @RequestHeader(ApiConstants.COUNTRY_HEADER) @ValidCountry final String country) {
// call the service
return ResponseEntity.status(HttpStatus.ACCEPTED).build();
}
答案 0 :(得分:1)
如果未正确设置所有部分,Spring会很难进行JSR303验证工作。我认为问题不在于请求标头,而在于某个地方的配置。我在这里给出一个最小的示例,说明如何配置基于注释的配置。
演示控制器
@Validated
@RestController
public class DemoController {
@GetMapping(path = "/endpoint")
public String createObject(@RequestHeader @ValidCountry String country) {
return "OK\n";
}
}
验证器类(将验证器作为内部类使其更简洁)
@Target({TYPE, FIELD, ANNOTATION_TYPE, ElementType.PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = ValidCountry.CountryValidator.class)
public @interface ValidCountry {
String message() default "Bad country";
Class<? extends Payload>[] payload() default {};
Class<?>[] groups() default {};
public static class CountryValidator
implements ConstraintValidator<ValidCountry, String> {
@Override
public boolean isValid(String value,
ConstraintValidatorContext context) {
return null!= value && value.length() > 1;
}
}
}
要完成所有这些工作,您还需要正确的依赖项(这是Maven风格):
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>6.1.5.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.5.Final</version>
</dependency>
我确信您会找到一种方法来放置允许验证者使用的允许国家/地区列表。
如果您使用CURL进行测试:
curl -H "country: fi" http://localhost:8080/endpoint
将返回 OK 。
curl -H "country: f" http://localhost:8080/endpoint
将失败。