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

Gab*_*lho 0 java class gson

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

 Response {
       BigDecimal price;
 }
 //json:
 {
     price: 20.20
 }
Run Code Online (Sandbox Code Playgroud)

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

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

例子:

class Response {
    Money value
}

Money {
    BigDecimal price;
}

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

//What I want:
{
    value : 20.20
} 
Run Code Online (Sandbox Code Playgroud)

Sot*_*lis 5

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
    }
}
Run Code Online (Sandbox Code Playgroud)

然后注册它。

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

现在将序列化为

{"value":20.20}
Run Code Online (Sandbox Code Playgroud)

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

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

与...一起使用

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(new Response(new Money(new BigDecimal("20.20"))));
Run Code Online (Sandbox Code Playgroud)

将生成

{"value":20.20}
Run Code Online (Sandbox Code Playgroud)

javadoc指出

与此类似的标记注释javax.xml.bind.annotation.XmlValue 指示注释的“getter”方法(这意味着签名必须是 getter 的签名;非 void 返回类型,无参数)的结果将用作实例的序列化的单个值。通常 value 是简单标量类型(StringNumber),但它可以是任何可序列化类型(CollectionMap或 Bean)。

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