2016-07-20 3 views
1

Я написал аннотацию для параметров запроса JAX-RS в сочетании с валидатором. Код выполняется, если ожидается.Исключение 400, брошенное из Validator, переустановлено в другое исключение с http-кодом 500

Цель состоит в том, чтобы отправить выбранный код состояния, например 400, если параметр запроса отсутствует. Джерси отправляет 404 по умолчанию, который не подходит.

Если исключение выбрасывается из конечной точки, его нормально: клиент получает ошибку 400.

Если исключение WebApplicationException выбрано из проверки подлинности, оно будет заменено на 500 ошибок.

Я мог бы катить метод в родительском классе моих конечных точек, который должен выполняться в начале каждой конечной точки w/обязательных параметров, но я бы предпочел бы согласованность, используя аннотацию.

Вопрос: Как я могу отправить исключение аннотации как есть для клиента?

Я уже пробовал пользовательские ExceptionMappers. Хотя аннотированный с @Provider и пакет, добавленный в список сканирования, они не используются. Даже ExceptionMapper < ConstraintViolationException>

Environment

Maven, Spring проект, основанный Джерси v2.23.1 okhttp 2.0.0 и 2.7.5 Tomcat 7.0.47 и 55 Джерси-боб-валидация в использовании

BV_SEND_ERROR_IN_RESPONSE: истинный BV_DISABLE_VALIDATE_ON_EXECUTABLE_OVERRIDE_CHECK: истинный

Аннотация

@Target({java.lang.annotation.ElementType.PARAMETER}) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy={MustExistValidator.class}) 
@ReportAsSingleViolation 
@Documented 
public @interface MustExist {...} 

Validator

@Provider 
@SupportedValidationTarget(ValidationTarget.PARAMETERS) 
public class MustExistValidator implements ConstraintValidator<MustExist, List<Integer>> { 
... 
@Override 
public boolean isValid(List<Integer> integerList, ConstraintValidatorContext context) 
{ 
    if (integerList == null || integerList.isEmpty()) { 
    context.disableDefaultConstraintViolation(); 
    //   throw ResourceException.emptyParameter(field); // custom Exception : a WebApplicationException w/ status 400 : becomes 500 (KO) 

    Response.ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST); 
    builder.entity("Missing 'indicators' query parameter."); 
    Response response = builder.build(); 
    throw new WebApplicationException(ResourceException.emptyParameter(field), response); 
// This is to populate a cause. So that its not replaced. KO too (500). 

    } 
    return true; 

}

+0

Мой вопрос отличается от http://stackoverflow.com/questions/29833553/jax-rs-service-throwing-a-404-httpexception-but-client-receiving-a-http-500-code ? rq = 1, поскольку я хочу исключить исключение из валидатора –

ответ

0

Ну, мое решение вписывается в категории "сделки с ним и работать вокруг".

К сожалению, исключение, специально заброшенное в валидаторе аннотации, обернуто jersey/tomcat.

Итак, мое решение состоит в том, чтобы написать картограф для обернутого исключения. Получите причину и сделайте то, что нужно сделать.

@Component 
@Provider 
public class ValidationExceptionMapper implements ExceptionMapper<ValidationException> { 

    @Override 
    public Response toResponse(ValidationException exception) { 
     if (exception.getCause() != null 
      && exception.getCause() instanceof WebApplicationException) {