Как мне зарегистрировать провайдера Jackson в клиенте Wink? - PullRequest
3 голосов
/ 02 декабря 2010

Я пытаюсь настроить игрушечное приложение (которое может когда-нибудь превратиться в настоящее приложение).У меня проблемы с Винком и Джексоном.У меня есть два приложения: одно запускает Wink-сервер на пристани и, кажется, отлично предоставляет некоторые данные JSON;один работает подмигивающий клиент на пристани и получает данные JSON просто отлично.Проблема заключается в автоматической десериализации данных JSON обратно в мой Java-бин.

Вот код, который я использую в своем клиентском действии wink:

RestClient client = new RestClient();
Resource resource = client.resource("http://localhost:8081/helloworld");
User user = resource.accept(MediaType.APPLICATION_JSON).get(User.class);

Вот ошибка, которую я получаю, когда пытаюсьзапустите действие Struts:

java.lang.RuntimeException: No javax.ws.rs.ext.MessageBodyReader found for type class my.package.structure.User and media type application/json. Verify that all entity providers are correctly registered.
org.apache.wink.client.internal.handlers.ClientResponseImpl.readEntity(ClientResponseImpl.java:123)
org.apache.wink.client.internal.handlers.ClientResponseImpl.getEntity(ClientResponseImpl.java:65)
org.apache.wink.client.internal.handlers.ClientResponseImpl.getEntity(ClientResponseImpl.java:52)
org.apache.wink.client.internal.ResourceImpl.invoke(ResourceImpl.java:186)
org.apache.wink.client.internal.ResourceImpl.get(ResourceImpl.java:294)
my.package.structure.action.HelloWorldAction.execute(HelloWorldAction.java:29)
...

Если я заменим последнюю строку в первом фрагменте кода на следующую строку, все будет работать нормально и шикарно.

String message = resource.accept(MediaType.APPLICATION_JSON).get(String.class);
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(message, User.class);

Понятно, что данныепроходит очень хорошо, но проблема, похоже, заключается в том, что класс JacksonJsonProvider не зарегистрирован в клиенте Wink.Я видел много способов зарегистрировать провайдера на сервере Wink, но не на клиенте Wink.

Можно ли сделать так, чтобы первый фрагмент кода работал правильно?Если да, то как?

(Кстати, другая проблема может заключаться в том, что я пропускаю аннотации в своем классе User. Сейчас их нет. Может быть, мне нужны ...)

Ответы [ 3 ]

7 голосов
/ 07 декабря 2010

Шаг 1. Создайте класс, расширяющий javax.ws.rs.core.Application, который позволяет вам устанавливать синглтоны.

import java.util.Collections;
import java.util.Set;
import javax.ws.rs.core.Application;

public class ClientApplication extends Application {

    private Set<Object> singletons = Collections.emptySet();

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }

    public void setSingletons(final Set<Object> singletons) {
        this.singletons = singletons;
    }
}

Шаг 2: в вашем действии создайте org.apache.wink.client.ClientConfig для вашего org.apache.wink.client.RestClient. Это позволяет добавить org.codehaus.jackson.jaxrs.JacksonJsonProvider в список поставщиков.

ClientApplication clientApplication = new ClientApplication();
Set<Object> s = new HashSet<Object>();
s.add(new JacksonJsonProvider());
clientApplication.setSingletons(s);
ClientConfig clientConfig = new ClientConfig().applications(clientApplication);
RestClient restClient = new RestClient(clientConfig);

Шаг 3: Создайте org.apache.wink.client.Resource, используйте метод get(Class<T> responseEntity), и все теперь будет работать как положено.

Resource resource = client.resource("http://localhost:8081/helloworld");
User user = resource.accept(MediaType.APPLICATION_JSON).get(User.class);

Если вы хотите быть действительно умным в этом, вы можете использовать Spring, чтобы настроить бин ClientConfig и добавить его в свои действия. Затем вы можете просто звонить new RestClient(clientConfig) каждый раз и не беспокоиться о репликации всей установки.

2 голосов
/ 01 августа 2014

Я столкнулся с этой проблемой, пытаясь написать несколько интеграционных тестов, которые POST-объект для моего плагина отдыха.

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

  @Before
public void setup(){

    javax.ws.rs.core.Application app = new javax.ws.rs.core.Application() {
        public Set<Class<?>> getClasses() {
            Set<Class<?>> classes = new HashSet<Class<?>>();
            classes.add(JacksonJaxbJsonProvider.class);
            return classes;
        }

    };
    //create auth handler
    clientConfig = new ClientConfig();
    clientConfig.applications(app);
    BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
    basicAuthSecurityHandler.setUserName(USERNAME);
    basicAuthSecurityHandler.setPassword(PASSWORD); 
    clientConfig.handlers(basicAuthSecurityHandler);
    //create client usin auth and provider
    client = new RestClient(clientConfig);

}

Затем вы можете публиковать и использовать ваши аннотированные объекты.

@Test
public void aReadWriteTokenCanBeCreatedAsRequested(){ 
    ClientResponse response = client.resource(resourceUrlToken).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(readAndWriteToken);
    assertEquals("Could not create token needed for test",200,response.getStatusCode());
    readAndWriteToken = response.getEntity(TokenResource.class);
    assertNotNull("Returned token does not have UUID",readAndWriteToken.getUuid());

}

Если вы используете maven, вы можете убедиться, что Джексон находится на тестовом пути к классам (проверьте совместимые версии):

<!-- TEST DEPENDENCIES -->
  <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-jaxrs</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-xc</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
  </dependency>
0 голосов
/ 03 декабря 2010

Хотелось бы помочь с регистрацией;но что касается аннотаций, я не думаю, что они нужны Джексону, чтобы попытаться десериализовать ценность.Если вы упустили что-то, что вам нужно, вы получите другое исключение.

...