2016-06-29 3 views
1

Что такое ContextResolver в Джерси и что такое Provider? Какая разница между двумя? Я использую Генсона с Джерси. Genson автоматически регистрируется, когда Джерси находит Jens Genson на пути к классам. Каталог WEB-INF/services Genson JAR содержит файл с именем org.glassfish.jersey.internal.spi.AutoDiscoverable.Что такое ContextResolver и провайдер в Джерси?

После этого AutoDiscoverable путь, по умолчанию Genson/Джерси автоматически регистрирует следующий класс:

@Provider 
@Consumes({MediaType.APPLICATION_JSON, "text/json", "application/*+json"}) 
@Produces({MediaType.APPLICATION_JSON, "text/json", "application/*+json"}) 
public class GensonJsonConverter implements MessageBodyReader<Object>, MessageBodyWriter<Object> { 

    private final ContextResolver<GensonJaxRSFeature> _gensonResolver; 

Вот где больше путаницы приходит в игру: глядя на документацию Genson он рекомендует, чтобы создать пользовательский поставщик, как так:

@Provider 
    public class GensonProvider implements ContextResolver<Genson> { 
    private final Genson genson = new GensonBuilder().setSkipNull(true).create(); 
    } 

Однако что поставщик реализует ContextResolver не MessageBodyReader/Writer, как внутренний Genson один делает. Какая разница? Кроме того, этот провайдер не делает то же самое, что и автоматически зарегистрированный! В частности, это игнорирует JAXB теги, такие как @XmlTransient! Копание в исходный код Genson для GensonJaxRSFeature, я вижу, что объект Genson создается следующим образом:

private static final Genson _defaultGenson = new GensonBuilder() 
     .withBundle(new JAXBBundle()) 
     .useConstructorWithArguments(true) 
     .create(); 

Из этого и из документации Genson я могу видеть, что «JAXBBundle», вероятно, что вызывает Genson обратить внимание в аннотации JAXB.

Основной вопрос:

Я хочу использовать по умолчанию поставщика в Genson JSON, который автоматически зарегистрирован Джерси, но я хочу, чтобы установить несколько пользовательских свойств на нем. Как я уже сказал, когда я регистрирую свой пользовательский провайдер, он не использует Genson по умолчанию!


Update:

Это то, что я делаю прямо сейчас, и это работает. Однако решение, приведенное @eugen, является рекомендуемым решением Genson.

@Provider 
public class GensonProvider implements ContextResolver<GensonJaxRSFeature> { 
    private final GensonJaxRSFeature _gensonResolver = new GensonJaxRSFeature(); 

    private static final Genson _defaultGenson = new GensonBuilder() 
       .withBundle(new JAXBBundle()) 
       .useConstructorWithArguments(true) 
       .setSkipNull(true) 
       .create(); 

    @Override 
    public GensonJaxRSFeature getContext(Class<?> type) { 
     return _gensonResolver.use(_defaultGenson); 
    } 
} 
+0

Почему вы говорите, что Genson рекомендует определить поставщика услуг? По крайней мере, в текущей документации рекомендуется использовать ResourceConfig, настроенный с помощью функции GensonJaxRSFeature, которая использует пользовательский экземпляр Genson. Вы не должны изменять экземпляр genson по умолчанию. Если вы хотите, чтобы другая конфигурация просто создала другой экземпляр с нужной конфигурацией. – eugen

+0

@eugen Посмотрите мое редактирование, чтобы посмотреть, что я сделал. Код, рекомендуемый в документах Genson, представляет собой «новый ResourceConfig(). Register (новый GensonJaxRSFeature(). Use (myCustomGenson) .disableSerializationFor (String.class));". Он делает то же, что и сейчас, но я использую Провайдер вместо того, где вы обычно добавляете новый код ResourceConfig. Где этот «новый ResourceConfig» обычно идет?Можете ли вы разместить пример или ссылку? – KyleM

+0

Проверьте [официальные документы] (https://jersey.java.net/documentation/latest/deployment.html#environmenmt.appmodel) о том, как использовать ResourceConfig. Невозможно взять экземпляр genson по умолчанию и изменить его. Просто предоставляйте свою собственную конфигурацию, которую вы хотите. И да, если вы хотите, чтобы Genson использовал аннотации JAXB, вам нужно настроить его для использования этого пакета. – eugen

ответ

2

Как всегда в нашем мире по той же проблеме существует множество решений. Джерси, кажется, поощряет использование ResourceConfig вместо определения пользовательских поставщиков. Таким образом, вы можете достичь этого, используя конфигурацию ресурсов (от dersey docs here и документацию Genson here).

public class MyApplication extends ResourceConfig { 
    public MyApplication() { 
     Genson genson = new GensonBuilder() 
       .withBundle(new JAXBBundle()) 
       .useConstructorWithArguments(true) 
       .setSkipNull(true) 
       .create(); 

     register(new GensonJaxRSFeature().use(genson)); 
    } 
} 

Но, конечно, так, как вы это делаете с поставщиком, тоже хорошо.

+0

Спасибо, я думаю, что я просто запутался b/c в документах Genson, который говорит, чтобы создать «новый ResourceConfig()», чего нет в этом решении. Вы создаете новый GensonBuilder, но никогда не новый ResourceConfig(). Во всяком случае, я понял это сейчас. Я в основном убедился, что у меня не хватает чего-то важного с помощью «нового ресурса ResourceConfig» ... – KyleM

+0

Нет, вы ничего не пропустите. Конфигурация ресурса, похоже, является местом, где джерси хочет, чтобы мы включили часть конфигурации, но ваше текущее решение тоже прекрасное. Да, здесь мы не создаем конфигурацию ресурсов, а расширяем ее. В некоторых других случаях использования Джерси люди могли бы создать экземпляр (я думаю, что это имеет дело с причалом + трикотаж). – eugen

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