0

Jersey 类似:具有 1 个元素的 Json 数组在客户端被序列化为对象 BUT。例如,我收到一个 JSON 对象,其中一个字段是一个数组,但如果只有一个元素,它就是一个对象。

{"fileInfo":[{"fileName":"weather.arff","id":"10"},"fileName":"supermarket.arff","id":"11"}]}

相对

{"fileInfo":{"fileName":"weather.arff","id":"10"}}

我正在使用 Jersey/Genson 解析/解组 JSON。当然,如果 JSON 与目标类不匹配,我会收到错误消息(例如expected [ but read '{'

我已经阅读了很多关于这个错误以及在服务器端创建 JSON 对象时如何避免的信息,但我没有发现在客户端处理时如何处理这个问题。

与往常一样,如果有多种解决方案,我更喜欢最无代码的可能性......

顺便说一句:Moxy 可以工作,但它不会编组本机 Object-type 对象,这是另一个要求......

4

1 回答 1

1

更新

Genson 1.3 版本开始,您可以通过启用 permissiveParsing 来实现它:

Genson genson = new GensonBuilder().usePermissiveParsing(true).create();

回答

呃,你知道哪个库在服务器端产生这个吗?我很想知道是谁对所有那些结构糟糕的 json 负责......

Genson 尚不支持它。最初是因为 IMO 的人不应该产生这样的动态 json。无论如何,我打开了一个问题- 这很容易完成,你可以期待它会出现在下周的版本中。

否则,这是一种在不破坏现有机制的情况下实现它的方法。您需要注册一个工厂,该工厂将使用 Gensons 集合工厂来创建其标准集合转换器的实例。然后,您将此转换器包装在另一个将对象处理为数组逻辑的转换器中。这是代码(不是无代码......,但如果你稍等一下,你就不必编码:))。

import com.owlike.genson.convert.DefaultConverters.CollectionConverterFactory;
import com.owlike.genson.convert.DefaultConverters.CollectionConverterFactory;


class SingleObjectAsCollectionFactory implements Factory<Converter<Collection>> {
  // get the default factory
  Factory<Converter<Collection<?>>> defaultFactory = CollectionConverterFactory.instance;


  @Override
  public Converter<Collection> create(Type type, Genson genson) {
    // obtain an instance of the correct default converter for this type
    final CollectionConverter defaultConverter = (CollectionConverter) defaultFactory.create(type, genson);

    // wrap it in your own converter
    return new Converter<Collection>() {

      @Override
      public void serialize(Collection object, ObjectWriter writer, Context ctx) throws Exception {
        defaultConverter.serialize(object, writer, ctx);
      }

      @Override
      public Collection deserialize(ObjectReader reader, Context ctx) throws Exception {
        if (reader.getValueType() == ValueType.OBJECT) {
          Object object = defaultConverter.getElementConverter().deserialize(reader, ctx);
          Collection result = defaultConverter.create();
          result.add(object);
          return result;
        } else return defaultConverter.deserialize( reader, ctx );
      }
    };
  }
}

然后注册

Genson genson = new GensonBuilder()
                  .withConverterFactory(new SingleObjectAsCollectionFactory())
                  .create();
于 2015-03-19T10:23:02.633 回答