web-dev-qa-db-fra.com

Jersey: MessageBodyWriter introuvable pour le type de support = application/json, type = classe org.codehaus.jackson.node.ObjectNode?

J'utilise Jersey 2.8 Client pour publier des données sur un terminal RESTful. Le code ressemble à

    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 () ressemble à

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

Lorsque j'essaie d'exécuter le test, l'erreur apparaît comme suit: 

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

Qu'est-ce que j'oublie ici?

Merci

15
daydreamer

Si vous acceptez l'utilisation de Jackson 1.x, vous devez tenir compte des trois éléments suivants.

1. Ajoutez Jersey Jackson à votre pom.xml:

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

2. Créer une 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. Enregistrez les fournisseurs avec 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);
9
Alden

J'ai ajouté un commentaire ci-dessus indiquant que l'ajout de X avait fonctionné.

Cependant, l'ajout de la dépendance maven suivante au fichier pom.xml fonctionne également et semble être un correctif plus standard.

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

Remarque: Le org.glassfish.jersey.archetypes/jersey-quickstart-grizzly maven archetype ajoute la dépendance ci-dessus par défaut, mais commenté avec le commentaire "décommentez ceci pour obtenir le support JSON".

7
Farskeptic

J'ai eu le même problème en essayant d'obtenir la réponse d'un serveur Apache sous PHP. Ma réponse du serveur était bonne, mais Spring se plaignait du message MessageBodyWriter introuvable pour le type application/json. J'ai ajouté la dépendance Genson à mon fichier pom.xml et cela a été corrigé!

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

La documentation est disponible sur: https://code.google.com/p/genson/

5
wingman88

essayez d'écrire le ObjectNode en tant que chaîne:

// 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));
1
herau