2011-01-03 3 views
0

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

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

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

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

+0

Какой интерфейс JSON вы используете в Bugzilla? Я являюсь автором интерфейса JSON-RPC, и я не могу представить ни одной ситуации, в которой это произойдет. Если это API REST, это совсем другая история - это отдельный продукт, который поддерживается отдельно. –

+0

Это API REST, который я использую. –

ответ

1

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":""}] 

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

0

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

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

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

+0

Если «текст» был объявлен типом Object, тогда Gson все еще задыхается над «текстом»: {}, жалуясь: «Информация типа недоступна, а целевой объект не является примитивным: {}". –