序列化一个 javax.measure.Quantity 属性
Serialize a javax.measure.Quantity property
如果我尝试将对象序列化为 JSON 并将其发送到 RESTful Web 服务,数量 属性 != null,我会收到以下错误
Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]->java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]-> ... (and so on))
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.loadHttpMethod(ApacheHttpClient4Engine.java:430)
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:281)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]->java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]->java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]-> ... (and so on))
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:694)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
...
(and so on)
这是简化的实体...
import javax.measure.Quantity;
import javax.measure.quantity.Mass;
public class Compound {
private Quantity<Mass> regAmount;
public Quantity<Mass> getRegAmount() {
return regAmount;
}
public void setRegAmount(Quantity<Mass> regAmount) {
this.regAmount = regAmount;
}
}
这是我如何设置值的示例:
Compound compound = new Compound();
double value = 1;
Unit<Mass> unit = Units.KILOGRAM;
Quantity<Mass> quantity = Quantities.getQuantity(value, unit);
compound.setRegAmount(quantity);
这是抛出错误的地方(适用于所有其他 20 个没有数量的实体):
Builder builder = ClientBuilder.newClient()
.target(webServiceUrl)
.path(path)
.request(MediaType.APPLICATION_JSON);
Entity<E> e = Entity.json(entity); // works
response = builder.put(e); // error if regAmount != null
使用的技术:Jackson, RestEasy, javax.measure.unit-api (ver. 1.0), tec.units.unit-ri (ver. 1.0.3)
问题:
- 你知道问题是什么以及如何解决这个问题吗?
- 是否有不同的方式来设置 regAmount?
- 您能推荐不同的方法或技术吗?
非常感谢!
JSR 363 与 Jackson 配合得很好,从 Opower(现为 Oracle)贡献的这个模块中可以看出 https://github.com/unitsofmeasurement/jackson-module-unitsofmeasure
它不使用 RI,虽然堆栈跟踪不是很透明,但可能的原因是,与 Java SE 端口 uom-se 不同的 RI 不使用 Serializable
.因为 RI 与 Java ME 8 Embedded 兼容并且不包含 Serializable。请尝试 uom-se,如果它解决了问题,请告诉我们。
我尝试了一些其他的接口实现,但没有成功。
我找到了一个足以满足 RESTful Web 服务目的的解决方案。因此,我使用了一个自定义序列化程序,它为我提供了数量的值和单位,这实际上是我在客户端重建数量所需的一切。
public class QuantitySerializer<Q extends Quantity<Q>> extends JsonSerializer<Quantity<Q>> {
@Override
public void serialize(Quantity<Q> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
try {
gen.writeNumberField("value", value.getValue().intValue());
gen.writeStringField("unit", value.getUnit().toString());
} catch (NullPointerException e) {}
gen.writeEndObject();
}
}
如果我尝试将对象序列化为 JSON 并将其发送到 RESTful Web 服务,数量 属性 != null,我会收到以下错误
Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]->java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]-> ... (and so on))
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.loadHttpMethod(ApacheHttpClient4Engine.java:430)
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:281)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]->java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]->java.util.ArrayList[0]->tec.units.ri.Identity["conversionSteps"]-> ... (and so on))
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:694)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
...
(and so on)
这是简化的实体...
import javax.measure.Quantity;
import javax.measure.quantity.Mass;
public class Compound {
private Quantity<Mass> regAmount;
public Quantity<Mass> getRegAmount() {
return regAmount;
}
public void setRegAmount(Quantity<Mass> regAmount) {
this.regAmount = regAmount;
}
}
这是我如何设置值的示例:
Compound compound = new Compound();
double value = 1;
Unit<Mass> unit = Units.KILOGRAM;
Quantity<Mass> quantity = Quantities.getQuantity(value, unit);
compound.setRegAmount(quantity);
这是抛出错误的地方(适用于所有其他 20 个没有数量的实体):
Builder builder = ClientBuilder.newClient()
.target(webServiceUrl)
.path(path)
.request(MediaType.APPLICATION_JSON);
Entity<E> e = Entity.json(entity); // works
response = builder.put(e); // error if regAmount != null
使用的技术:Jackson, RestEasy, javax.measure.unit-api (ver. 1.0), tec.units.unit-ri (ver. 1.0.3)
问题:
- 你知道问题是什么以及如何解决这个问题吗?
- 是否有不同的方式来设置 regAmount?
- 您能推荐不同的方法或技术吗?
非常感谢!
JSR 363 与 Jackson 配合得很好,从 Opower(现为 Oracle)贡献的这个模块中可以看出 https://github.com/unitsofmeasurement/jackson-module-unitsofmeasure
它不使用 RI,虽然堆栈跟踪不是很透明,但可能的原因是,与 Java SE 端口 uom-se 不同的 RI 不使用 Serializable
.因为 RI 与 Java ME 8 Embedded 兼容并且不包含 Serializable。请尝试 uom-se,如果它解决了问题,请告诉我们。
我尝试了一些其他的接口实现,但没有成功。
我找到了一个足以满足 RESTful Web 服务目的的解决方案。因此,我使用了一个自定义序列化程序,它为我提供了数量的值和单位,这实际上是我在客户端重建数量所需的一切。
public class QuantitySerializer<Q extends Quantity<Q>> extends JsonSerializer<Quantity<Q>> {
@Override
public void serialize(Quantity<Q> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
try {
gen.writeNumberField("value", value.getValue().intValue());
gen.writeStringField("unit", value.getUnit().toString());
} catch (NullPointerException e) {}
gen.writeEndObject();
}
}