Проблема десериализации Bugzilla JSON с помощью Google Gson - PullRequest
0 голосов
/ 03 января 2011

Я столкнулся с проблемой в JSON. Я получаю ответ от сервера Bugzilla, потому что он иногда возвращает «text»: {}, а иногда «text»: «бла-бла-бла». Bugzilla возвращает первое, если не было дано описание ошибки. Я озадачен, почему это не возвращается как гораздо более разумный «текст»: «», но это так и есть.

Если у меня есть текст с именем String в целевом объекте для Gson, он возражает, когда видит случай {}, потому что говорит, что это объект, а не строка:

Exception in thread "main" com.google.gson.JsonParseException: The 
JsonDeserializer StringTypeAdapter failed to deserialized json object {} given 
the type class java.lang.String

Любые предложения о том, как я могу заставить Gson разобрать это?

Ответы [ 2 ]

1 голос
/ 10 июня 2011

Gson требует пользовательской десериализации для ситуации в исходном вопросе. Ниже приведен один из таких примеров.

input.json:

[
  {
    "text":"some text"
  },
  {
    "text":{}
  }
]

Foo.java:

import java.io.FileReader;
import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(String.class, new StringDeserializer());
    Gson gson = gsonBuilder.create();
    Thing[] things = gson.fromJson(new FileReader("input.json"), Thing[].class);
    System.out.println(gson.toJson(things));
  }
}

class Thing
{
  String text;
}

class StringDeserializer implements JsonDeserializer<String>
{
  @Override
  public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException
  {
    if (json.isJsonPrimitive()) return json.getAsString();
    return "";
  }
}

Выход:

[{"text":"some text"},{"text":""}]

Конечно, возможно использование нестандартного десериализатора для типа Thing.class. Это дает преимущество в том, что вы не добавляете дополнительную обработку для каждого String, но тогда вы застрянете с «ручной» обработкой всех других атрибутов Thing.

0 голосов
/ 03 января 2011

Попробуйте объявить поле text как Object. Затем сделайте что-то вроде:

public String getTextAsString() {
    if (text instanceof String) {
        return (String) text;
    else {
        return null;
    }
}

Вы должны сообщить об этом как об ошибке в проект Bugzilla. Нет веских причин для такого поведения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...