GSON Java Throwable - PullRequest
       25

GSON Java Throwable

10 голосов
/ 16 ноября 2011

У меня есть объект, который содержит часть данных и связанную исключительную ситуацию.

Public class MyBean{
  Private String data;
  Private Exception problem;
.
.
.
}

Когда я пытаюсь GSON.toJSON (объект) , это дает мне циркулярссылки ошибка с жалобой на поле «проблема».

Есть ли способ для GSON обрабатывать такие объекты?

Ответы [ 4 ]

18 голосов
/ 20 ноября 2011

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

Следующий пример демонстрирует эту точку.

import com.google.gson.Gson;

public class GsonFoo
{
  public static void main(String[] args)
  {
    MyBean bean = new MyBean();
    bean.data = "some data";
    bean.problem = new RuntimeException("Ack!");

    System.out.println(new Gson().toJson(bean));
  }
}

class MyBean
{
  public String data;
  public Exception problem;
}

Этот примерприводит к следующему исключению и сообщению от Gson.

Exception in thread "main" java.lang.IllegalStateException: circular reference error
  Offending field: cause

  Offending object: preserveType: false, type: class java.lang.Throwable, obj: java.lang.RuntimeException: Ack!
    at com.google.gson.CircularReferenceException.createDetailedException(CircularReferenceException.java:43)
    at com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:117)
...

Gson также задыхается при попытке выполнить что-то простое:

System.out.println(new Gson().toJson(new RuntimeException("Ack!")));

Gson в настоящее время не имеет конфигурации, доступной длярешить эту проблему.Я рекомендую регистрировать проблему в http://code.google.com/p/google-gson/issues/list.

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

import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class GsonFoo
{
  public static void main(String[] args)
  {
    MyBean bean = new MyBean();
    bean.data = "some data";
    bean.problem = new RuntimeException("Ack!");

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Exception.class, new ExceptionSerializer());
    Gson gson = gsonBuilder.create();

    System.out.println(gson.toJson(bean));
  }
}

class ExceptionSerializer implements JsonSerializer<Exception>
{
  @Override
  public JsonElement serialize(Exception src, Type typeOfSrc, JsonSerializationContext context)
  {
    JsonObject jsonObject = new JsonObject();
    jsonObject.add("cause", new JsonPrimitive(String.valueOf(src.getCause())));
    jsonObject.add("message", new JsonPrimitive(src.getMessage()));
    return jsonObject;
  }
}

class MyBean
{
  public String data;
  public Exception problem;
}

вывод:

{"data":"some data","problem":{"cause":"null","message":"Ack!"}}

Для чего стоит, Джексон не аналогичноДроссель при попытке сериализации той же структуры данных.Джексон сериализует экземпляр MyBean в JSON следующим образом.

{
  "data":"some data",
  "problem":
  {
    "cause":null,
    "message":"Ack!",
    "localizedMessage":"Ack!",
    "stackTrace":
    [
      {
        "className":"com.stackoverflow.q8151082.JacksonFoo",
        "fileName":"JacksonFoo.java",
        "lineNumber":11,
        "methodName":"main",
        "nativeMethod":false
      }
    ]
  }
}
3 голосов
/ 16 ноября 2014

Я знаю, что это не ответ на конкретный вопрос (на который был дан правильный ответ более чем за 2 года) Но:

для тех, кто получает это исключение в других случаях:

эта ошибка возникает при попытке разобрать сложное поле, которое gson не знает для разбора.

если вам нужно это поле в вашем классе, но не для разбора, и вы хотите исключить его из анализа gson, вы можете:

  • добавьте аннотацию @Expose ко всем полям, которые вы хотите проанализировать , (что-то вроде @Expose private Long id;)
  • объявить объект Gson следующим образом:

    Gson gson = new GsonBuilder (). ExcludeFieldsWithoutExposeAnnotation (). Create ();

Вот что мне помогло

0 голосов
/ 31 января 2018

Я также столкнулся с той же проблемой в Gson версии 2.2.2. В Gson версии 2.6.1 я не вижу этой проблемы.

0 голосов
/ 16 ноября 2011

GSON может обрабатывать другие пользовательские классы как атрибуты вашего первого класса, но используете ли вы его таким образом?

gson.fromJson(yourResponse,MyBean.class)

и исключение является одним из ваших пользовательских классов?Может быть, если может конфликтовать с java.lang.Exception.

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