Разбор JSON, который имеет атрибуты, которые могут прийти в виде строки или массива строк - PullRequest
0 голосов
/ 31 марта 2019

У меня есть вложенный json, где во внутреннем массиве есть несколько ключей, значениями которых могут быть либо строковый массив, либо массив массивов строк.Формат JSON не соответствует.Как мне разобрать такой json с помощью gson.

Я попытался написать собственный десериализатор (см. Gson - разбор json с полем, которое является массивом или строкой ), но которое выбрасываетисключение даже до того, как я смог обнаружить атрибут как строку или массив и затем соответствующим образом обновить атрибут.

мой json похож на этот

{
"hits" : {
  "total" : 100,
  "max_score" : 1,
  "hits": [
      {"_index": "s1",     
       "_source":{
          "activeOrExpired":[
            ["active"]
          ]
        }
       },
      {"_index": "s1",
       "_source":{
          "activeOrExpired":[
             "expired"
          ]
        }
      }    
    ]
  }
}

Мои классы java

public class OuterJson {
    @SerliazedName("hits")
    public Hits hitsOuter;
    public static class Hits {
        public List<InnerHits> innerHits;
    }
}

public InnerHits {
    public String _index;
    public Source _source;
    public static class Source {
        public List<List<String>> activeOrExpired;//I declare this field as                             
                                                 //list of list of strings
        public Source() {
            activeOrExpired = new ArrayList<>();
        }
    }
}

public class CustomDeserializer implements JsonDeserializer<OuterJson> {
    @Override
    public OuterJson deserialize(JsonElement elem, Type type, JsonDeserializationContext context) throws JsonParseException {
        JsonObject outerObj = elem.getAsJsonObject();
        JsonElement innerHits = outerObj.get("hits").getAsJsonObject().get("hits");
        //I want to then detect the type of "activeOrExpired" and convert it         
        //to list of list of strings if it is present just as a string

        //I am getting exception in the below line
        InnerHits[] innerHitsArray = new Gson().fromJson(innerHits, InnerHits[].class);

      //omitting below code for brevity since my code is failing above itself.
    }
}

Исключением является

java.lang.IllegalStateException: Expected BEGIN_ARRAY but was String at path $[0]._source.activeOrExpired[0]

Здесь самый внутренний массив "совпадений" имеет массив "_source", который имеет поле "activeOrExpired", это поле поступает либо как массив строк, либо как массив массивов строк,Как мне разработать специальный десериализатор для такого случая?Я новичок в GSON и следовал метод, упомянутый в ссылке выше.Мой код описан выше, может кто-нибудь дать мне подсказку о прогрессе.Спасибо!

1 Ответ

0 голосов
/ 31 марта 2019

Вы можете использовать DSM потоковую библиотеку для анализа такого сложного JSON или XML. Используя DSM, вам не нужно создавать файл-заглушку Java для десериализации. Вы можете напрямую десериализовать в свой собственный класс. Он использует файл сопоставления на основе YAML.

Вот решение вашего вопроса. Я не уверен насчет структуры вашего объекта. Я только десериализовал некоторую его часть.

Файл сопоставления:

result:
    type: object  # result is map.
    path: /hits
    fields:
      hits:
        path: hits
        type: array
        fields:
          index:
            path: _index
          source:  
            path: _source/activeOrExpired
            filter: $value!=null
            type: array    # source is also array. 

Используйте DSM для фильтрации JSON и десериализации .

// you can pass your class to deserialize directly to your class instead of getting  map or list as a result.
//DSM dsm=new DSMBuilder(new File("path/to/maping.yaml")).create(YourClass.class);

DSM dsm=new DSMBuilder(new File("path/to/maping.yaml")).create();
Map<String,Object> hits= (Map<String,Object>)dsm.toObject(new File("path/to/data.json");

json представление попаданий переменная

{
  "innerHits" : [ {
    "index" : "s1",
    "source" : [ "active" ]
  }, {
    "index" : "s1",
    "source" : [ "expired" ]
  } ]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...