2014-05-12 7 views
15

Używam Jersey 2.8 Client do publikowania danych do RESTful punktu końcowego. Kod wyglądaJersey: Nie znaleziono MessageBodyWriter dla media type = application/json, type = class org.codehaus.jackson.node.ObjectNode?

final Client client = ClientBuilder.newClient(); 
    final WebTarget target = client.target(url).path("inventorySummary"); 
    final Invocation.Builder builder = target.request().header("Content-Type", MediaType.APPLICATION_JSON); 

    final ObjectNode payload = getObjectMapper().createObjectNode(); 
    payload.put("startDate", DateTime.now().toString()); 
    payload.put("endDate", DateTime.now().plusDays(30).toString()); 
    payload.put("networkId", 0); 

    final Response response = builder.accept(MediaType.APPLICATION_JSON).post(Entity.entity(payload, MediaType.APPLICATION_JSON)); 
    assertStatus(Response.Status.OK.getStatusCode(), response); 
    final JsonNode jsonReply = parseResponse(response); 

getObjectMapper() wygląda

public ObjectMapper getObjectMapper() { 
     return new ObjectMapper() 
       .configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false /* force ISO8601 */) 
       .configure(SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, true) 
       .configure(DeserializationConfig.Feature.READ_ENUMS_USING_TO_STRING, true) 
       .setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS); 
    } 

Kiedy próbuję uruchomić test, widzę błąd jako

MessageBodyWriter not found for media type=application/json, type=class org.codehaus.jackson.node.ObjectNode, genericType=class org.codehaus.jackson.node.ObjectNode 

Co ja tu brakuje?

Dzięki

+0

Wygląda na to, że używasz pliku Jackson 1.x. Czy możesz uaktualnić do wersji Jackson 2.x i spróbować ponownie? – geoand

+0

czy dodałeś genson.jar? Jeśli nie, spójrz na tę odpowiedź: http://stackoverflow.com/questions/17503748/jax-rs-jersey-json-http-500-internal-server-error/30003820#30003820 – CtrlX

Odpowiedz

9

Jeśli ok używając Jackson 1.x, to trzeba 3 następujących rzeczy.

1. Dodaj Jersey Jacksona do pom.xml:

<dependency> 
    <groupId>org.glassfish.jersey.media</groupId> 
    <artifactId>jersey-media-json-jackson</artifactId> 
    <version>2.8</version> 
</dependency> 

2. Stwórz ContextResolver:

@Provider 
public class ObjectMapperProvider implements ContextResolver<ObjectMapper> { 

    final ObjectMapper defaultObjectMapper; 

    public ObjectMapperProvider() { 
     defaultObjectMapper = getObjectMapper(); 
    } 

    @Override 
    public ObjectMapper getContext(Class<?> type) { 
     return defaultObjectMapper; 
    } 

    public static ObjectMapper getObjectMapper() { 
     return new ObjectMapper() 
       .configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false /* force ISO8601 */) 
       .configure(SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, true) 
       .configure(DeserializationConfig.Feature.READ_ENUMS_USING_TO_STRING, true) 
       .setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS); 
    } 
} 

3. dostawców zarejestrować się ClientBuilder:

final Client client = ClientBuilder.newBuilder() 
     .register(ObjectMapperProvider.class) 
     .register(JacksonFeature.class) 
     .build(); 

final WebTarget target = client.target(url).path("inventorySummary"); 

final ObjectNode payload = ObjectMapperProvider.getObjectMapper().createObjectNode(); 
payload.put("startDate", DateTime.now().toString()); 
payload.put("endDate", DateTime.now().plusDays(30).toString()); 
payload.put("networkId", 0); 

final Response response = target.request(MediaType.APPLICATION_JSON) 
           .post(Entity.json(payload)); 

assertStatus(Response.Status.OK.getStatusCode(), response); 
+3

Myślę, że to również w sensie dodawania importu, ponieważ zajęło mi trochę czasu, aby dowiedzieć się, które zależności pozwalają uzyskać te klasy do użytku z Jersey 2.x (i są to: 'javax.ws.rs:javax.ws.rs-api ',' com.fasterxml.jackson.core: jackson-databind', 'com.fasterxml.jackson.module: jackson-module-jaxb-adnotations',' com.fasterxml.jackson.core: jackson-adnotations'). – carlspring

5

Miałem ten sam problem podczas próby uzyskania odpowiedzi z serwera Apache z uruchomionym PHP. Moja odpowiedź była dobra z serwera, ale Spring skarżyła się, że MessageBodyWriter nie został znaleziony dla aplikacji typu/json. Dodałem zależność Gensona do mojego pliku pom.xml i naprawiłem go!

<dependency> 
     <groupId>com.owlike</groupId> 
     <artifactId>genson</artifactId> 
     <version>0.99</version> 
    </dependency> 

dokumentację można znaleźć na stronie: https://code.google.com/p/genson/

+0

Miałem identyczny błąd używając Grizzly, i dodanie powyższego do mojego pom.xml również go naprawiło. Żadne inne zmiany nie były wymagane. – farskeptic

+0

Zobacz mój post poniżej, ale dla bardziej standardowego pakietu. – farskeptic

1

spróbować napisać ObjectNode jako String:

// your code 
final ObjectNode payload = getObjectMapper().createObjectNode(); 
payload.put("startDate", DateTime.now().toString()); 
payload.put("endDate", DateTime.now().plusDays(30).toString()); 
payload.put("networkId", 0); 

// the solution 
String entity = getObjectMapper().writeValueAsString(payload); 

final Response response = builder.accept(MediaType.APPLICATION_JSON).post(Entity.entity(entity, MediaType.APPLICATION_JSON)); 
6

dodałem komentarz powyżej stwierdzając, że dodanie X pracował.

Jednak dodanie do pom.xml również zależności maven działa i wydaje się bardziej standardową poprawką.

 <dependency> 
     <groupId>org.glassfish.jersey.media</groupId> 
     <artifactId>jersey-media-moxy</artifactId> 
    </dependency> 

Uwaga: org.glassfish.jersey.archetypes/Jersey quickstart-grizzly Maven archetyp dodaje zależność powyżej domyślnie, ale wykomentowane z komentarzem "Odkomentuj to uzyskać wsparcie JSON" .

+2

Dodanie pliku jersey-media-json-jackson jako zależności pom rozwiązuje również problem –