泽西岛:找不到媒体类型 = 应用程序/json、类型 = 类 org.codehaus.jackson.node.ObjectNode 的 MessageBodyWriter?

Posted

技术标签:

【中文标题】泽西岛:找不到媒体类型 = 应用程序/json、类型 = 类 org.codehaus.jackson.node.ObjectNode 的 MessageBodyWriter?【英文标题】:Jersey: MessageBodyWriter not found for media type=application/json, type=class org.codehaus.jackson.node.ObjectNode? 【发布时间】:2014-06-29 09:23:22 【问题描述】:

我正在使用Jersey 2.8 Client 将数据发布到 RESTful 端点。代码看起来像

    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() 看起来像

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

当我尝试运行测试时,我看到错误为

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

我在这里错过了什么?

谢谢

【问题讨论】:

您似乎使用的是 Jackson 1.x。您可以升级到 Jackson 2.x 并重试吗? 您添加了 genson.jar 吗?如果没有,看看这个答案:***.com/questions/17503748/… 【参考方案1】:

如果你可以使用 Jackson 1.x,那么你需要做以下 3 件事。

1.将 Jersey Jackson 添加到您的 pom.xml:

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

2。创建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.向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);

【讨论】:

我认为添加导入也是有意义的,因为我花了一段时间才弄清楚从哪些依赖项中获取这些类以用于 Jersey 2.x(它们是: javax.ws.rs:javax.ws.rs-apicom.fasterxml.jackson.core:jackson-databindcom.fasterxml.jackson.module:jackson-module-jaxb-annotationscom.fasterxml.jackson.core:jackson-annotations)。【参考方案2】:

我在上面添加了一条评论,说明添加 X 有效。

但是,将以下 maven 依赖项添加到 pom.xml 也可以,并且似乎是一个更标准的修复方法。

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

注意:org.glassfish.jersey.archetypes/jersey-quickstart-grizzly maven 原型默认添加了上面的依赖项,但用注释注释掉了 “取消注释以获取 JSON支持”

【讨论】:

添加 jersey-media-json-jackson 作为 pom 依赖也可以解决问题【参考方案3】:

我在尝试从运行 php 的 Apache 服务器获取响应时遇到了同样的问题。我的服务器响应很好,但是 Spring 抱怨找不到类型 application/json 的 MessageBodyWriter。我将 Genson 依赖项添加到我的 pom.xml 并修复了它!

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

可以在以下位置找到文档:https://code.google.com/p/genson/

【讨论】:

我在使用 Grizzly 时遇到了同样的错误,将上述内容添加到我的 pom.xml 中也修复了它。无需进行其他更改。 查看我下面的帖子以获得更标准的包。【参考方案4】:

尝试将 ObjectNode 写为字符串:

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

【讨论】:

以上是关于泽西岛:找不到媒体类型 = 应用程序/json、类型 = 类 org.codehaus.jackson.node.ObjectNode 的 MessageBodyWriter?的主要内容,如果未能解决你的问题,请参考以下文章

严重:找不到媒体类型 = 应用程序/json、类型 = 类 com.jersey.jaxb.Todo、通用类型 = 类 com.jersey.jaxb.Todo 的 MessageBodyWriter

找不到 Java 类 java.util.ArrayList 和 MIME 媒体类型 application/json 的消息正文编写器

严重:找不到 Java 类 java.util.ArrayList 和 MIME 媒体类型 application/json 的消息正文编写器

泽西岛的 JSON ArrayList

找不到类型的响应对象的 MessageBodyWriter:媒体类型的 java.util.LinkedHashMap:application/json

找不到 MessageBodyWriter 类型的响应对象:com.sun.jersey.api.json.JSONWithPadding 媒体类型:application/x-javascript