使用 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,请查看 。
以下代码使用具有内置 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,请查看