Frage

Ich versuche, eine Spielzeug-Anwendung einrichten (die zu einem realen Anwendung eines Tag drehen-in). Ich laufe in ein Problem mit Wink und Jackson. Ich habe zwei Anwendungen bekommt: ein Lauf wink-Server auf Anlegestelle und scheint ganz gut einige JSON-Daten zu bieten; läuft man blinzeln-Client auf Anlegestelle und empfängt die Daten JSON just fine. Das Problem liegt in automagically die JSON-Daten zurück in meinen Java Bean Deserialisieren.

Hier ist der Code, den ich in meinem Zwinkern Client-Aktion verwenden:

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

Hier ist der Fehler, den ich erhalte, wenn ich versuche, die Struts Aktion auszuführen:

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)
...

Wenn ich die letzte Zeile in dem ersten Codeausschnitt mit der folgenden Zeile ersetzen, funktioniert alles schön und gut.

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

Es ist klar, dass die Daten über ganz gut bekommen, aber das Problem scheint darin zu liegen, dass die JacksonJsonProvider Klasse nicht mit Wink-Client registriert ist. Ich habe eine Menge von Möglichkeiten gesehen, den Anbieter mit dem Wink-Server zu registrieren, aber nicht das Wink-Client.

Ist es möglich, den ersten Code zu tun, macht Schnipsel richtig funktionieren? Wenn ja, wie?

(Nebenbei kann das andere Problem, dass ich auf meine Anmerkungen User-Klasse fehlt bin. Im Moment gibt es keine. Vielleicht brauche ich einige ...)

War es hilfreich?

Lösung

Schritt 1:. Erstellen Sie eine Klasse, die javax.ws.rs.core.Application erstreckt, die Sie Satz Singletons erlaubt

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

Schritt 2: In Ihrer Aktion, erstellen Sie eine org.apache.wink.client.ClientConfig für Ihre org.apache.wink.client.RestClient. Dadurch können Sie die org.codehaus.jackson.jaxrs.JacksonJsonProvider auf Ihren Provider-Liste hinzufügen.

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

Schritt 3: Erstellen Sie die org.apache.wink.client.Resource, verwenden Sie die get(Class<T> responseEntity) Methode und alles wird jetzt wie erwartet.

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

Wenn Sie wirklich glatt über sie sein wollen, können Sie Frühling verwenden, um eine ClientConfig Bohne einzurichten und zu injizieren sie in auf Ihre Aktionen. Dann können Sie nur new RestClient(clientConfig) rufen jedes Mal, und nicht die Sorge um die gesamte Einrichtung zu replizieren.

Andere Tipps

Ich lief in dieses Problem bei dem Versuch, einige Integrationstests, dass POST ein Objekt für meine Ruhe Plugin zu schreiben.

Rather dann eine neue Klasse Spinnen aus Sie den Jackson-Provider mit einer Inline-Klasse zur Verfügung stellen können.

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

}

Dann können Sie Beiträge verfassen und verbrauchen Ihre kommentierten Objekte.

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

}

Wenn Sie mit maven Sie sicherstellen können, Jackson auf dem Test Classpath ist (Check für kompatible Versionen):

<!-- 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>

Ich wünschte, ich mit der Registrierung helfen könnte; aber in Bezug auf Anmerkungen, ich glaube nicht, dass Sie jede für Jackson zu deserialisieren Wert zu versuchen brauchen sollten. Wenn Sie etwas vermissen müssen Sie Sie andere Art der Ausnahme erhalten würde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top