序列化javax.measure.Quantity属性

时间:2017-11-03 08:06:01

标签: java json builder units-of-measurement

如果我尝试将Object序列化为JSON并将其发送到具有Quantity属性的RESTful Web服务!= null,则会出现以下错误

Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (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 (StackOverflowError) (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(版本1.0),tec.units.unit-ri(版本1.0.3)

问题:

  1. 您知道问题是什么以及如何解决此问题?
  2. 有没有不同的方法来设置regAmount?
  3. 您能推荐不同的方法或技术吗?
  4. 提前多多感谢!

2 个答案:

答案 0 :(得分:1)

我尝试了其他一些接口实现,但没有运气。

我找到了一个足以满足RESTful Web服务目的的解决方案。因此,我使用了一个自定义的Serializer,它给出了Quantity的值和单位,这实际上是我在客户端重建Quantity所需的一切。

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

答案 1 :(得分:0)

JSR 363与杰克逊合作很好,正如本单元所见,来自Opower(现为Oracle)的贡献https://github.com/unitsofmeasurement/jackson-module-unitsofmeasure

它不使用RI,虽然堆栈跟踪不是很透明,但可能的原因是,与Java SE端口uom-se不同的RI不使用Serializable。因为RI与Jav​​a ME 8 Embedded兼容,并且不包括Serializable。如果它解决了问题,请尝试uom-se并告诉我们。

相关问题