【问题标题】:Serialize a javax.measure.Quantity property序列化 javax.measure.Quantity 属性
【发布时间】:2018-04-15 21:45:07
【问题描述】:

如果我尝试将对象序列化为 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. 您能推荐不同的方法或技术吗?

提前非常感谢!

【问题讨论】:

    标签: java json builder units-of-measurement


    【解决方案1】:

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

    我找到了一个足以满足 RESTful Web 服务目的的解决方案。因此,我使用了一个自定义序列化程序,它为我提供了 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();
        }
    }
    

    【讨论】:

    • 你是如何使用这个自定义序列化程序的,确切地说?
    【解决方案2】:

    JSR 363 与 Jackson 配合得很好,如本模块所示,该模块源自 Opower(现为 Oracle)https://github.com/unitsofmeasurement/jackson-module-unitsofmeasure 的贡献。

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

    【讨论】:

    • 好吧 - uom.se 不适用于 GeoTools - {code} java.lang.NoSuchMethodError: tec.uom.se.format.SimpleUnitFormat.getInstance()Ltec/uom/se/format/ SimpleUnitFormat {代码}
    • 您使用的确切依赖项是什么?这个线程主要是关于用 Jackson 序列化 JSR 363 或 385,那么你是否尝试使用 JSON 来做到这一点?
    猜你喜欢
    • 2011-08-04
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多