使用JSON-B将UUID序列化为JSON中的规范十六进制字符串

时间:2018-07-23 22:12:54

标签: java json data-binding binding jsonb-api

UUID

universally unique identifier (UUID)是一个128位值。用java.util.UUID类在Java中表示。

十六进制字符串

为了显示和进行序列化,它被规范地格式化为36个字符的十六进制字符串,该字符串按连字符分隔,分为五个组。 For example
fd95cb46-8ec3-11e8-9eb6-529269fb1459

使用Java标准XML和JSON API进行序列化时,我希望使用此十六进制字符串。适用于XML,但不适用于JSON。我没有为XML或JSON使用任何类型的注释。我简单的POJOXML也不JSON一无所知。

XML =成功

当我使用JSR 222: JavaTM Architecture for XML Binding (JAXB) 2.0的标准XML绑定框架生成XML时,就成功了。我得到预期的十六进制字符串。请参阅此代码段的最后一个元素:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<panel>
    <connected>3.4kVA</connected>
    <fedFrom>PANEL 'EHE1' &amp; ATS-EM</fedFrom>
    <grounding>ground bus</grounding>
    <id>89d14b92-35ae-4c0c-b61d-ea8dbdeb324b</id>

JSON =失败

当我通过JSR 367: JavaTM API for JSON Binding (JSON-B)的标准JSON绑定框架运行相同的panel对象时,会失败。我得到的是数字,而不是预期的十六进制字符串。

{"connected":"3.4kVA","fedFrom":"PANEL 'EHE1' & ATS-EM","grounding":"ground bus","id":{"leastSignificantBits":-5323841289984462261,"mostSignificantBits":-8515942329042973684},

如果滚动,您将看到名为id的UUID以一对数字而不是十六进制字符串的形式出现:

  

“ id”:{“ leastSignificantBits”:-5323841289984462261,“ mostSignificantBits”:-8515942329042973684}

是否有某种方法可以使JSON绑定像XML绑定那样工作?我想要的是十六进制字符串,而不是一对64位数字。

当然,当将已编组的值重新编组为Java对象时,该编组的值应该起作用。

1 个答案:

答案 0 :(得分:2)

JSON-B规范没有提及UUID类型,因此,是否提供开箱即用的(反)序列化器取决于实现。但是,如果您使用的是Eclipse Yasson(JSON-B ref impl),则默认情况下会提供UUID(反)序列化器。我不确定默认情况下其他JSON-B标签(例如Apache Johnzon)会提供什么。

如果您使用的是Yasson,我建议在their GitHub repo上打开一个错误,因为这应该可以工作。


自定义方式

如果您使用的是默认情况下不提供UUID适配器的JSON-B实现,则可以创建并注册自己的类型适配器:

public static class MyUUIDAdapter implements JsonbAdapter<UUID, String> {

    @Override
    public String adaptToJson(UUID obj) throws Exception {
        return obj.toString();
    }

    @Override
    public UUID adaptFromJson(String obj) throws Exception {
        return UUID.fromString(obj);
    }

}

注册适配器的最简单方法是在创建Jsonb实例时:

Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withAdapters(new MyUUIDAdapter()));

但是,如果您不控制自己的Jsonb实例的实例化(例如JAX-RS在后台进行实例化),则可以注释字段/方法以在以下位置使用适配器:

public class Panel {
    @JsonbTypeAdapter(MyUUIDAdapter.class)
    public UUID id;
}