2016-07-29 4 views
4

В настоящее время у меня есть этот запрос, где я выполняю проверку на Request Param с помощью REGEX.Пользовательская проверка на RequestHeader Spring Boot

@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) String apiKeyHeader) { 

    // Stuff here... 
} 

Так я могу проверить с рисунком:

@RequestHeader(value = "X-API-Key", required = true) @Valid @Pattern(regexp = SEGMENTS_REGEX) String apiKeyHeader 

Но я хотел бы сделать некоторые пользовательские проверки на атрибут заголовка т.е.

if (!API_KEY_LIST.contains(apiKeyHeader)) { 
    throw Exception(); 
} 
+0

@RequestHeader (значение = "X-API-Key", required = true) @Valid @Pattern (regexp = SEGMENTS_REGEX) String apiKeyHeader Не могли бы вы сообщить мне, что вышеуказанная линия работает для вас? – Lathy

ответ

1

1) Проверьте вручную

Вы можете ввести HttpServletRequest и che ck заголовки.

@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); 
    } 
} 

2) Вводить заголовке

@RequestMapping(value = "/test", method = RequestMethod.POST) 
public ResponseEntity<String> test(@RequestHeader(value="myheader") String myheader){ 
    return new ResponseEntity<String>(HttpStatus.OK); 
} 

, который будет возвращать:

{ 
    "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" 
} 

если заголовок отсутствует.

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(); 
} 

Пропустить Запросить

Если вы используете атрибут заголовки в @RequestMapping

@RequestMapping(value = "/test", method = RequestMethod.POST, 
    headers = {"content-type=application/json"}) 

это приведет к 404, если там нет никакого другого обработчика принять запрос.

+0

Для опции № 3: как мы будем использовать этот фильтр для возврата неверного запроса ответа, если заголовок не был отправлен правильно? – IcedDante

+0

@IcedDante См. Ответы здесь: https: // stackoverflow.com/questions/23621037/return-http-error-401-code-skip-filter-chains –

3

Лучший способ сделать это ММО, чтобы создать пользовательский 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; 
     } 
    } 
} 

Затем контроллер подписи выглядит следующим образом:

@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... 
} 

Вы зарегистрируете обработчик аргумента метода обработчика в WebMvcConfigurationAdapter:

@Configuration 
public class MvcConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { 
     argumentResolvers.add(segmentHandler()); 
    } 

    @Bean 
    public SegmentHandlerMethodArgumentResolver segmentHandler() { 
     return new SegmentHandlerMethodArgumentResolver(); 
    } 

} 
+0

Почему это называется «Сегмент»? – MariuszS

Смежные вопросы