java - 对于 GF4 和 Jackson,未找到 Media type=application/json 的 MessageBodyWriter

标签 java json rest maven glassfish

每次尝试调用 REST 服务时,我都会收到以下错误消息

[2016-09-01T16:27:37.782+0200] [Payara 4.1] [SEVERE] []   [org.glassfish.jersey.message.internal.WriterInterceptorExecutor] [tid: _ThreadID=28 _ThreadName=http-listener-1(3)] [timeMillis: 1472740057782] [levelValue: 1000] [[MessageBodyWriter not found for media type=application/json, type=class xxx.JsonClass, genericType=class xxx.JsonClass.]]

这是 REST 服务(删除相关部分):

import javax.ejb.EJB;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;


@Path("/service")
public class Service {

  @GET
  @Path("/callme")
  @Produces(MediaType.APPLICATION_JSON)
  public JsonClass callme(//
      @QueryParam("test") final String test, //
       ....) {
    return new JsonClass();
  }
}

JSON 类

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

public class JsonClass {

  private String test;

  public JsonClass(final String test....) {
   ...
  }

  @JsonProperty
  public String getTest() {
    return this.test;
  }
}

POM.xml(有趣的部分)

<!-- DO NOT change the scope for jersey: https://java.net/jira/browse/JERSEY-1941 -->
<dependency>
  <groupId>org.glassfish.jersey.media</groupId>
  <artifactId>jersey-media-json-jackson</artifactId>
  <version>2.8</version>
  <scope>provided</scope>
</dependency>

我的设置是:

  • JDK8/JEE7(内部版本 1.8.0_51-b16)
  • Glassfish 4.1 Payara
  • Maven 3.2.5

这是我到目前为止尝试过的:

我仍然认为这是一个依赖问题。但是我不知道可能出现什么问题。

最佳答案

不幸的是,尽管问题和解决方案不同,但我的上一篇文章被标记为重复。因此,我发布了一个包含两个解决方案的新问题,希望能帮助您避免在 table 上敲几个小时的头。

首选解决方案:

显然 GF4 附带了我不想使用的 MoxyJson。要集成您自己的依赖项(在我的例子中为 Jackson),您需要使用以下代码禁用 MoxyJson。

@ApplicationPath("/")
public class ApplicationConfig extends Application {

  /**
   * {@inheritDoc}
   */
  @Override
  public Map<String, Object> getProperties() {
    final Map<String, Object> properties = new HashMap<String, Object>();
    properties.put("jersey.config.server.disableMoxyJson", true);

    return properties;
  }
}

然后添加您自己的依赖项,例如就我而言,只有这两个,因为其他的被我使用的另一个库引用。

<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.6.2</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>2.6.2</version>
</dependency>

最后,我犯了一个错误,没有为 @JsonProperty 注释设置值,这将导致 No MessageBodyWriter found 异常。为了避免这种情况,请使用以下与您的类相关的 getter。

@JsonProperty("randomName")
public String getRandomName(){
...
}

替代方案:

比上面更糟糕的是,您需要禁用 MoxyJson,单独注册每个服务,并修复使用 GF 的 ResourceConfig 时的 Bug。

@ApplicationPath("/")
public class ApplicationConfig extends ResourceConfig {

/**
* The default constructor.
*/
public ApplicationConfig() {

// Disable Moxy and use Jackson
this.property(ServerProperties.MOXY_JSON_FEATURE_DISABLE, true);

// Register own provider classes
this.register(Fully.Qualified.Path.To.Your.Service.class);

// Register Jackson provider
// Workaround for GF4.1 bug for details: https://java.net/jira/browse/GLASSFISH-21141
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JaxbAnnotationModule());
this.register(new JacksonJaxbJsonProvider(mapper, JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS));
}
}

您需要 ResourceConfig 类的额外依赖项。

 <dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.6.2</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>2.6.2</version>
</dependency>

<dependency>
  <groupId>org.glassfish.main.extras</groupId>
  <artifactId>glassfish-embedded-all</artifactId>
  <version>4.1.1</version>
  <scope>provided</scope>
</dependency>

最后与上面相同 - 请注意使用带有设定值的@JsonProperty。

关于java - 对于 GF4 和 Jackson,未找到 Media type=application/json 的 MessageBodyWriter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39881226/

相关文章:

java - 如何使用包含完全相同类型的参数但使用其他类型参数化的参数列表的方法重载方法

java - 将许多对象绘制到 JPanel 上的替代方法

JSON 未从 yarn REST API 返回

java - Swagger 是否也适用于 Jersey 2.x?

ruby - Github API 响应 'Content is not valid Base64'

java - 从 C++ 调用 java 代码 : exception java. lang.NoSuchMethodError

java - Elasticsearch (Java) 禁用日志记录

javascript - 如何使用handlebars来处理这样复杂的JSON数据?

javascript - 将 php 数组从外部 php 文件传递​​给 javascript 函数

rest - 纯粹为了使用 HTTP 请求正文而发布