Gson. Десериализовать в список объектов Java новых элементов с нулевым идентификатором

1

У меня есть дерево элементов ol и li. Я добавляю этот элемент динамически. После этого я хотел бы десериализовать их в объект java. К сожалению, я получаю сообщение об ошибке:

SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/derp] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause java.lang.NullPointerException at com.derp.generic.model.GenericModel.getId(GenericModel.java:28)

Я знаю, что это происходит, потому что у моих новых элементов dosnt есть id. Но это должно быть так, причина Id генерируется на сервере базы данных. Обычно id я буду делать такой A think (create object assign parameters throught seters, но без id), ошибки не будет. И после этого этот новый объект получит идентификатор.

То же самое я пытаюсь достичь здесь. После правильной десериализации я хотел бы сохранить этот объект и создать Id для него.

Но я должен сказать моему строителю Gson разрешить null или не попробовать установить параметр, который не объявлен (имеет значение null).

Вот мой код:

public List<SkeletonElement> toObject(String jsonObject) {
    Gson gson = new GsonBuilder()
                .serializeNulls()
                .registerTypeAdapter(Long.class, new LongTypeAdapter())
                .create();
    List<SkeletonElement> list = gson.fromJson(jsonObject, new TypeToken<List<SkeletonElement>>(){}.getType());
    return list;
}

Пользовательский адаптер, который должен выполнить трюк:

package com.derp.generic.helpers;

import java.io.IOException;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

public class LongTypeAdapter extends TypeAdapter<Long>{
@Override
public Long read(JsonReader reader) throws IOException {
    if(reader.peek() == JsonToken.NULL){
        reader.nextNull();
        return null;
    }
    String stringValue = reader.nextString();
    try{
        Long value = Long.valueOf(stringValue);
        return value;
    }catch(NumberFormatException e){
        return null;
    }
}
@Override
public void write(JsonWriter writer, Long value) throws IOException {
    if (value == null) {
        writer.nullValue();
        return;
    }
    writer.value(value);
}
}

Общая модель, где id объявлен:

@MappedSuperclass
public abstract class GenericModel<T extends GenericModel<?>> {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;


    public long getId() {return id;}
    public void setId(long id) {this.id = id;}

    public GenericModel() {
    }

    public GenericModel(Long id) {
        super();
        this.id = id;
    }
}

И объект json с объектом null id в конце

[
    {
        "name": "Title1",
        "id": "1",
        "type": "SkeletonJobElement",
        "parent_id": "null",
        "children": [
            {
                "name": "Title11",
                "id": "2",
                "type": "SkeletonJobElement",
                "parent_id": "1",
                "children": [
                    {
                        "name": "Title111",
                        "id": "5",
                        "type": "SkeletonFileElement",
                        "parent_id": "2",
                        "children": []
                    },
                    {
                        "name": "Title112",
                        "id": "6",
                        "type": "SkeletonFileElement",
                        "parent_id": "2",
                        "children": []
                    }
                ]
            }
        ]
    },
    {
        "name": "Title2",
        "id": "3",
        "type": "SkeletonJobElement",
        "parent_id": "null",
        "children": [
            {
                "name": "Title21",
                "id": "4",
                "type": "SkeletonJobElement",
                "parent_id": "3",
                "children": []
            }
        ]
    },
    {
        "name": "Title3",
        "id": "null",
        "type": "SkeletonJobElement",
        "parent_id": "null",
        "children": []
    }
]
  • 0
    Ошибка возникает в строке 28 вашего класса GenericModel , но указанный класс содержит всего ~ 19 строк. Вы обрезали это? Проверьте первую ошибку в нижней части трассировки стека. В любом случае, похоже, что id вашего подкласса GenericModel равен null зависимости от ошибки. Попробуйте изменить тип id getter / setters на Long , чтобы соответствовать переменной экземпляра, к которой они изменяют / получают доступ.
  • 0
    Да. Я обрезал ненужные строки. 28-я строка - это public long getId() {return id;} Это public long getId() {return id;} сначала в json!
Теги:
deserialization
gson
primary-key

2 ответа

2
Лучший ответ

Этот метод возвращает примитивный long. Вы не можете вернуть null из этого метода.

public long getId() { return id; }

Измените тип возврата на Long. Переменная экземпляра, возвращаемая этим методом, может быть null, но сам метод не может.

public Long getId() { return id; }

Сделайте то же самое с установщиком.

public void setId(Long id) { this.id = id; }

Вы также можете проверить значение null перед возвратом.

public long getId() { id == null ? 0L : id.longValue(); }
  • 0
    И теперь это работает. Благодарю. Это было достаточно, чтобы перейти от примитивного длинного объекта к длинному
0

Если возможно, измените getId, чтобы вернуть длинный объект, а не примитивный. Автоматическое преобразование в примитивное длинное приводит к исключению нулевого указателя.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню