使用 Moxy 和 JerseyClient2 发布编组通用

Issue marshalling generic with Moxy and JerseyClient2

以下代码使用具有内置 Moxy JSON 支持的 Jersey2 客户端 (v 2.22.2)。我正在尝试将通用包装器 class 编组为 JSON。正如您在下面看到的,json 属性 没有按预期解组。

当我将 json 属性 的类型更改为 Service 和 'ungenerify' class 时,一切都按预期工作,但我更愿意能够用泛型做到这一点,所以我不必为需要以这种方式包装的每种类型创建一堆这些包装器 classes。

JSONWrapper.java

public class JSONWrapper<T> implements Serializable {
  private T json;

  public T getJson() { return this.json; }
  public void setJson (T payload) { this.json = payload; }

  public JSONWrapper() {}
}

Service.java

public class Service implements Serializable {
    private String name;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

MyClient.java

public class MyClient {
  private Client jerseyClient;

  public void createService(Service item) {
    Invocation.Builder invocationBuilder = buildRequest(SERVICE_PATH);
    JSONWrapper<Service> wrapper = new JSONWrapper<>();
    wrapper.setJson(item);
    final Response response = invocationBuilder.post(Entity.entity(wrapper, MediaType.APPLICATION_JSON_TYPE));
  }

  public MyClient() {
     this.jerseryClient = ClientBuilder.newBuilder().build();
  }

  public static void main(String[] args) {
     MyClient myClient = new MyClient();
     Service myService = new Service();
     myService.setName("foo");
     myClient.createService(myService);
  }
}

打开日志过滤器后,我看到 Moxy 的编组看起来像这样:

{"json":"com.baz.Service@5674e1f2"}

当我希望它看起来像这样时

{"json":"{"name": "foo"}"}

由于类型擦除,泛型在运行时被擦除,所以 MOXy 不知道泛型,只是吐出它的 toString。这是使用 MOXy 的限制之一(它依赖于某些 JAXB 功能)。为了解决这个问题,JAX-RS 有 GenericEntity 让我们包装泛型类型,因此序列化程序知道它。

JsonWrapper<Service> service = new JsonWrapper<>();
user.setJson(new Service("blah"));
GenericEntity<JsonWrapper<Service>> entity 
        = new GenericEntity<JsonWrapper<Service>>(service){};
Response response = target("test").request().post(Entity.json(entity));

根据我刚刚用 MOXy 测试的结果,出于某种原因,它在 JSON 中吐出一个额外的 "type":"service" 属性。我不完全确定为什么。我已经有一段时间没有使用 MOXy 了。我遇到了太多问题。就个人而言,我建议切换到 Jackson。使用 Jackson,您将不会遇到此类问题。您可以使用 GenericEntity 而不是 而不是 ,它会解决这个问题。如果您使用的是 Maven,只需添加以下依赖项并删除 MOXy

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>${jersey2.version}</version>
</dependency>

如果您不使用 Maven,请查看