【发布时间】:2014-12-22 18:18:19
【问题描述】:
我有 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)
我知道这是因为我的新元素没有 ID。但这意味着要这样,因为 Id 是在数据库服务器上生成的。通常 id 我会做这样的思考(通过 setter 创建对象分配参数,但没有 id)不会有错误。在持久化之后,这个新对象将获得一个 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;
}
}
最后是带有空id对象的json对象
[
{
"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": []
}
]
【问题讨论】:
-
GenericModel类的第 28 行发生错误,但您提供的类只有约 19 行。你截断了吗?检查堆栈跟踪底部的第一个错误。无论如何,根据错误,您的GenericModel子类的id看起来是null。尝试将idgetters/setters 的类型更改为Long,以匹配它们正在变异/访问的实例变量。 -
是的。我已经截断了不需要的行。第 28 行是
public long getId() {return id;}它是 null 因为 null 一开始在 json 中!
标签: java json gson deserialization primary-key