如何在Gson中将对象序列化为单个值?

时间:2016-11-21 16:10:01

标签: java class gson

当你有一个要转换为json的类时,如果它包含一个BigDecimal属性,它将返回一个像这样的json:

 Response {
       BigDecimal price;
 }
 //json:
 {
     price: 20.20
 }

请注意,BigDecimal是一个类。它的行为就像一个原语(整数,浮点数)。

我想产生相同的行为(一个类将一个信息返回给json)

示例:

class Response {
    Money value
}

Money {
    BigDecimal price;
}

//What is returning:
{
    value : { price: 20.20 }
}

//What I want:
{
    value : 20.20
} 

1 个答案:

答案 0 :(得分:4)

Gson没有开箱即用的功能。你需要自己实现它。

如果仅适用于Response类型,您只需实施自己的TypeAdapter即可。

class ResponseTypeAdapter extends TypeAdapter<Response> {
    @Override
    public void write(JsonWriter out, Response value) throws IOException {
        out.beginObject();
        out.name("value");
        // check for null, if applicable, and use a default value, or don't write anything at all
        out.value(value.getValue().getPrice());
        out.endObject();
    }

    @Override
    public Response read(JsonReader in) throws IOException {
        // implement the deserialization
    }
}

然后注册。

Gson gson = new GsonBuilder().registerTypeAdapter(Response.class, new ResponseTypeAdapter()).create();
// test it
String json = gson.toJson(new Response(new Money(new BigDecimal("20.20"))));

现在将序列化为

{"value":20.20}

如果您可以使用杰克逊,它会附带一个@JsonValue注释,可以为您执行此操作。例如,

class Money {
    private final BigDecimal price;
    public Money(BigDecimal bigDecimal) {
        this.price = bigDecimal;
    }
    @JsonValue // <<< this
    public BigDecimal getPrice() {
        return price;
    }
}

一起使用
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(new Response(new Money(new BigDecimal("20.20"))));

将生成

{"value":20.20}

javadoc

  

javax.xml.bind.annotation.XmlValue 类似的标记注释   表示带注释的“getter”方法的结果(表示   签名必须是getter的签名;非void返回类型,没有args)   用作序列化实例的单个值。平时   value将是一个简单的标量类型(StringNumber),但它可以   是任何可序列化的类型(CollectionMap或Bean)。

     

最多可以使用此注释对类的一个方法进行注释;   如果找到多个,则可能抛出异常。另外,如果方法   签名与Getters不兼容,可能会抛出异常   (是否抛出异常是一个实现细节(到期)   在内省过滤时,可能会跳过一些注释)   和应用程序不应该依赖于特定的行为。)