使用 JSON-B 将 UUID 序列化为 JSON 中的规范十六进制字符串
Serialize a UUID as canonical hex string in JSON using JSON-B
UUID
A universally unique identifier (UUID) is a 128-bit value. Represented in Java by the java.util.UUID
class.
十六进制字符串
为了显示和序列化,它被规范地格式化为 36 个字符的十六进制字符串,分为五组,由连字符分隔。 For example:
fd95cb46-8ec3-11e8-9eb6-529269fb1459
当使用 Java-标准 XML 和 JSON API 进行序列化时,我希望得到这个十六进制字符串。为 XML 工作,但为 JSON 工作失败。我没有对 XML 或 JSON 使用任何类型的注释。我的简单 POJO knows nothing of XML nor 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' & ATS-EM</fedFrom>
<grounding>ground bus</grounding>
<id>89d14b92-35ae-4c0c-b61d-ea8dbdeb324b</id>
JSON = 失败
当我 运行 相同的 panel
对象通过 JSR 367: JavaTM API for JSON Binding (JSON-B) 的标准 JSON 绑定框架时,失败。我得到的不是预期的十六进制字符串,而是数字。
{"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 对象中。
JSON-B 规范没有提及 UUID 类型,因此是否提供开箱即用的(反)序列化器取决于实现。但是,如果您使用的是 Eclipse Yasson(JSON-B ref impl),它会默认提供一个 UUID(反)序列化器。我不确定其他 JSON-B impls(例如 Apache Johnzon)默认提供什么。
如果您使用的是 Yasson,我建议您在 their GitHub repo 上打开一个错误,因为这应该有效。
自定义方式
如果您使用的 JSON-B 实现默认不提供 UUID 适配器,您可以创建并注册您自己的类型适配器:
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 在幕后进行),您可以注释 field/method 以在以下位置使用适配器:
public class Panel {
@JsonbTypeAdapter(MyUUIDAdapter.class)
public UUID id;
}
UUID
A universally unique identifier (UUID) is a 128-bit value. Represented in Java by the java.util.UUID
class.
十六进制字符串
为了显示和序列化,它被规范地格式化为 36 个字符的十六进制字符串,分为五组,由连字符分隔。 For example:fd95cb46-8ec3-11e8-9eb6-529269fb1459
当使用 Java-标准 XML 和 JSON API 进行序列化时,我希望得到这个十六进制字符串。为 XML 工作,但为 JSON 工作失败。我没有对 XML 或 JSON 使用任何类型的注释。我的简单 POJO knows nothing of XML nor 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' & ATS-EM</fedFrom>
<grounding>ground bus</grounding>
<id>89d14b92-35ae-4c0c-b61d-ea8dbdeb324b</id>
JSON = 失败
当我 运行 相同的 panel
对象通过 JSR 367: JavaTM API for JSON Binding (JSON-B) 的标准 JSON 绑定框架时,失败。我得到的不是预期的十六进制字符串,而是数字。
{"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 对象中。
JSON-B 规范没有提及 UUID 类型,因此是否提供开箱即用的(反)序列化器取决于实现。但是,如果您使用的是 Eclipse Yasson(JSON-B ref impl),它会默认提供一个 UUID(反)序列化器。我不确定其他 JSON-B impls(例如 Apache Johnzon)默认提供什么。
如果您使用的是 Yasson,我建议您在 their GitHub repo 上打开一个错误,因为这应该有效。
自定义方式
如果您使用的 JSON-B 实现默认不提供 UUID 适配器,您可以创建并注册您自己的类型适配器:
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 在幕后进行),您可以注释 field/method 以在以下位置使用适配器:
public class Panel {
@JsonbTypeAdapter(MyUUIDAdapter.class)
public UUID id;
}