GSON。反序列化为具有null id的新元素的java对象列表

时间:2014-12-22 18:18:19

标签: java json gson deserialization primary-key

我有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(通过setter创建对象分配参数,但没有id)将没有错误。坚持下去后,这个新对象将获得一个id。

我想在这里实现同样的目标。在正确的反序列化后,我想坚持这个对象,这将为他创建一个Id。

但我必须告诉我的Gson构建器允许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对象的结尾为空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": []
    }
]

2 个答案:

答案 0 :(得分: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(); }

答案 1 :(得分:0)

如果可能,更改getId以返回Long对象而不是原始long。自动转换为原始long会导致空指针异常。