Jersey / Genson:解组单个对象数组

时间:2015-03-18 17:39:25

标签: json jaxb jersey jax-rs genson

类似于客户端的Jersey: Json array with 1 element is serialized as object但是。例如。我收到一个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 '{'

我已经阅读了很多关于这个bug的内容以及如何在SERVER端创建JSON对象时避免这种错误,但是我在CLIENT方面处理时没有发现如何处理这个问题。

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

BTW:Moxy可以工作,但它不会编组本地对象类型的对象,这是另一个要求......

1 个答案:

答案 0 :(得分:1)

<强>更新

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

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

<强>答案

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

Genson尚不支持。原来是因为IMO人不应该产生这样的动态json。无论如何,我打开an issue - 这很容易做到,你可以期待它出现在下周发布的版本中。

否则,这是一种在不破坏现有机制的情况下实现它的方法。 您需要注册一个工厂,该工厂将使用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();