У меня есть дерево элементов 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": []
}
]
Этот метод возвращает примитивный 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(); }
Если возможно, измените getId, чтобы вернуть длинный объект, а не примитивный. Автоматическое преобразование в примитивное длинное приводит к исключению нулевого указателя.
GenericModel
, но указанный класс содержит всего ~ 19 строк. Вы обрезали это? Проверьте первую ошибку в нижней части трассировки стека. В любом случае, похоже, чтоid
вашего подклассаGenericModel
равенnull
зависимости от ошибки. Попробуйте изменить типid
getter / setters наLong
, чтобы соответствовать переменной экземпляра, к которой они изменяют / получают доступ.public long getId() {return id;}
Этоpublic long getId() {return id;}
сначала в json!