2016-07-31 1 views
8

В одном из моих проектов я уже обновил Джерси с версии 2.14 до 2.23. Но я борюсь много часов с одной проблемой. Мой проект определяет его собственный ExceptionMapper для ValidationException, но, к сожалению, у Джерси уже есть встроенный редактор исключений для этого исключения, и я не могу его переопределить.Как переопределить встроенный редактор исключений в Jersey 2.23?

Я зарегистрировал правильно (я проверил) мой собственный картограф, который представлен ниже:

@Provider 
public class ValidationExceptionMapper implements 
     ExceptionMapper<ValidationException> { 

    @Override 
    public Response toResponse(ValidationException exception) { 
     return Response.status(Status.BAD_REQUEST).build(); 
    } 
} 

, но она никогда не вызывается. Джерси всегда забирает org.glassfish.jersey.server.validation.internal.ValidationExceptionMapper. Я также попытался использовать аннотацию @Priority для моего настраиваемого картографа, но, к сожалению, Джерси не учитывает это.

Итак, что же происходит? Он работал отлично в предыдущей версии Джерси, поэтому, похоже, это ошибка регрессии.

Я сдаюсь. Любые подсказки?

+0

Вы можете использовать 'ConstraintViolationException' (который является фактическим типом исключений проверки) в качестве работы. Это более специфично, чем 'ValidationException', поэтому оно будет иметь приоритет. Я никогда не выяснял, как отключить этот один картограф, не отключая поставщиков _all_ meta-inf (а не веселое решение). Моя работа заключалась в том, чтобы просто использовать mapper для 'ConstraintViolationException' –

+0

Спасибо, я знаю это, но это не решает проблему вообще. Поскольку приложение должно отвечать на 'ValidationException'. –

+0

'ConstraintViolationException' расширяет' ValidationException'. Тип исключения, созданный с проверкой компонента в Джерси, всегда будет «ConstraintViolationException». Он работает для 'ValidationException', потому что супермашины типа могут обрабатывать исключения подтипа, нет ли сопоставителя для подтипа –

ответ

4

Он действительно оказался регресс ошибка в Джерси, введенная в январе 2015 года

ошибки связана с двумя расширениями Джерси: для Weld и проверки компоненты. Поскольку без контейнера Weld мой пользовательский ValidationExceptionMapper картограф имеет преимущество перед встроенным модулем jersey-bean-validation, поэтому моя цель достигнута.

Я заполнил отчет об ошибке под номером JERSEY-3153.

Если честно, я никогда больше не буду использовать Weld + Jersey снова ... Я так устал от этой комбинации. За последние два года я уже встречал около 10 ошибок. Я действительно устал.

В любом случае, я надеюсь, что это поможет кому-то.

UPDATE: Как @Justin Хосе заметил в комментариях ниже, есть и другой способ решения указанной ошибки. Мы можем использовать ¯hk2 привязки, чтобы переопределить проблемный встроенный картограф:

register(new AbstractBinder() { 
    @Override 
    protected void configure() { 
     bind(my.custom.ValidationExceptionMapper.class).to(ExceptionMapper.class) 
       .in(Singleton.class); 
    } 
}); 
0

Я нашел способ, чтобы заставить его работать с новым Джерси выпускает снова, который я также отправил под отчетом об ошибке.

Нужно построить Джерси на месте с измененным кодом, в частности артефактом jersey-bean-validation.

Расположить org.glassfish.jersey.server.validation.internal.ValidationBinder и закомментируйте следующие две строки в configure():

bind(ValidationExceptionMapper.class).to(ExceptionMapper.class).in(Singleton.class); 
bind(ValidationErrorMessageBodyWriter.class).to(MessageBodyWriter.class).in(Singleton.class); 

Это отчасти парадоксально, что исходный код комментарий выше этих линий говорит, что они должны позволить пользователям регистрировать свои собственные поставщики.

+0

Спасибо Hein, но я хотел бы рассмотреть возможность исправления библиотеки в последнюю очередь ... –

4

Встроенная функция ValidationExceptionMapper встроена в ValidationFeature. Вероятно, замена «ValidationFeature» Джерси на вашу собственную версию может сделать трюк. Это можно сделать следующим образом.

Во-первых, отключить автоматическое обнаруживаемым ValidationFeature

property(ServerProperties.BV_FEATURE_DISABLE, true); 

Следующий шаг заключается в регистрации клон функции

public static class ValidationFeatureClone implements Feature { 

    @Override 
    public boolean configure(FeatureContext context) { 
     context.register(new ValidationBinder()); 
     context.register(NewValidationExceptionMapper.class); 
     context.register(ValidationErrorMessageBodyWriter.class); 
     return true; 
    } 
} 

проверки Джерси В клоне, вам следует указать свой новый ExceptionMapper.

Наконец, зарегистрировать ваш новый Feature

register(ValidationFeatureClone.class) 

UPDATE:

Джерси 2.20 и далее, по умолчанию ValidationExceptionMapper могут быть перезаписаны с помощью связывания, как показано ниже HK2.

register(new AbstractBinder() { 
@Override 
protected void configure() { 
    bind(NewValidationExceptionMapper.class).to(ExceptionMapper.class) 
      .in(Singleton.class).ranked(10‌​); 
} 

});

+0

Пожалуйста, дважды проверьте свое решение. Я проверил его минуту назад с Джерси 2.23.1, и он не решает исходную проблему вообще. Кроме того, 'ValidationErrorMessageBodyWriter' не является общедоступным классом. –

+0

Я использую Jersey 2.19 в нашем приложении, и решение сработало для нас. Похоже, что начиная с версии 2.20 'ValidationErrorMessageBodyWriter' изменен на пакет-частный класс. Я не заметил вашего упоминания об 2.23 в вашем исходном вопросе. Можете ли вы попробовать создать клон 'ValidationErrorMessageBodyWriter'? –

+0

Похоже, что в последних версиях пользовательский 'ValidationExceptionMapper' может быть зарегистрирован с использованием привязки HK2, и нет необходимости регистрировать клон функции Validation, как я упоминал в своем первоначальном ответе. Можете ли вы попробовать добавить 'зарегистрируйтесь (новый AbstractBinder() { \t \t \t \t \t \t @Override \t \t \t защищен недействительным Configure() { \t \t \t \t связывания (NewValidationExceptionMapper.class) .то (ExceptionMapper.class) .в (Singleton.class) .ranked (10); \t \t \t \t \t \t \t} \t \t}); ' –

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