pti*_*son 7 java validation spring spring-boot spring-rest
我目前有这个RequestMapping
,我通过正则表达式使用验证:
@RequestMapping(value = "/example/{id}", method = GET)
public Response getExample(
@PathVariable("id") String id,
@RequestParam(value = "myParam", required = true) @Valid @Pattern(regexp = MY_REGEX) String myParamRequest,
@RequestParam(value = "callback", required = false) String callback,
@RequestHeader(value = "X-API-Key", required = true) @Valid @Pattern(regexp = SEGMENTS_REGEX) String apiKeyHeader) {
// Stuff here...
}
Run Code Online (Sandbox Code Playgroud)
然而,正则表达是不够的.相反,我想对header属性进行一些自定义验证,即
if (!API_KEY_LIST.contains(apiKeyHeader)) {
throw Exception();
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?
执行此操作的最佳方法IMO是HandlerMethodArgumentResolver
使用自定义注释创建看起来像这样的自定义@Segment
:
public class SegmentHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(String.class)
&& parameter.getParameterAnnotation(Segment.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String apiKey = webRequest.getHeader("X-API-Key");
if (apiKey != null) {
if (!API_KEY_LIST.contains(apiKey)) {
throw new InvalidApiKeyException();
}
return apiKey;
} else {
return WebArgumentResolver.UNRESOLVED;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后您的控制器签名如下所示:
@RequestMapping(value = "/example/{id}", method = GET)
public Response getExample(
@PathVariable("id") String id,
@RequestParam(value = "myParam", required = true) @Valid @Pattern(regexp = MY_REGEX) String myParamRequest,
@RequestParam(value = "callback", required = false) String callback,
@Segment String apiKeyHeader) {
// Stuff here...
}
Run Code Online (Sandbox Code Playgroud)
您将在WebMvcConfigurationAdapter中注册处理程序方法参数解析程序:
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(segmentHandler());
}
@Bean
public SegmentHandlerMethodArgumentResolver segmentHandler() {
return new SegmentHandlerMethodArgumentResolver();
}
}
Run Code Online (Sandbox Code Playgroud)
1)手动检查
您可以注入 HttpServletRequest 并检查标头。
@RestController
public class HomeController {
public ResponseEntity<String> test(HttpServletRequest request){
if(request.getHeader("apiKeyHeader") == null){
return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<String>(HttpStatus.OK);
}
}
Run Code Online (Sandbox Code Playgroud)
2)注入标头
@RequestMapping(value = "/test", method = RequestMethod.POST)
public ResponseEntity<String> test(@RequestHeader(value="myheader") String myheader){
return new ResponseEntity<String>(HttpStatus.OK);
}
Run Code Online (Sandbox Code Playgroud)
这将返回:
{
"timestamp": 1469805110889,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.web.bind.ServletRequestBindingException",
"message": "Missing request header 'myheader' for method parameter of type String",
"path": "/test"
}
Run Code Online (Sandbox Code Playgroud)
如果标头丢失。
3)使用过滤器
如果您想在多种方法上使用某些过滤器,您可以使用某些过滤器自动进行检查。在您的自定义过滤器中,只需获取标头(如方法 1 中所示),如果标头丢失,只需响应 400 或您想要的任何内容。对我来说,当您不在控制器方法中使用标头值而只需要验证它是否存在时,这是有意义的。
@Bean
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(apiHeaderFilter());
registration.addUrlPatterns("/example/*");
registration.setName("apiHeaderFilter");
registration.setOrder(1);
return registration;
}
@Bean(name = "ApiHeaderFilter")
public Filter apiHeaderFilter() {
return new ApiHeaderFilter();
}
Run Code Online (Sandbox Code Playgroud)
跳过请求
如果您在 @RequestMapping 中使用 headers 属性
@RequestMapping(value = "/test", method = RequestMethod.POST,
headers = {"content-type=application/json"})
Run Code Online (Sandbox Code Playgroud)
如果没有其他处理程序来接受请求,这将导致 404。
归档时间: |
|
查看次数: |
22869 次 |
最近记录: |