универсальный уникальный идентификатор (UUID) - это 128-битное значение. Представлен в Java классом java.util.UUID.
Для отображения и для сериализации он канонически отформатирован как шестнадцатеричная строка из 36 символов, разбитая на пять групп, разделенных дефисом. Например: fd95cb46-8ec3-11e8-9eb6-529269fb1459
При сериализации с использованием стандартных Java API XML и JSON я ожидаю эту шестнадцатеричную строку. Работал с XML, но не с JSON. Я не использую никаких аннотаций ни для XML, ни для JSON. Мой простой POJO ничего не знает ни о XML, ни о JSON.
Когда я создаю XML, используя стандартную структуру привязки XML JSR 222: Архитектура JavaTM для привязки XML (JAXB) 2.0, успех. Я получаю шестнадцатеричную строку, как и ожидалось. См. Последний элемент этого фрагмента:
<?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>
Когда я запускаю тот же объект panel через стандартную структуру привязки JSON JSR 367: API JavaTM для привязки JSON (JSON-B), происходит сбой. Вместо ожидаемой шестнадцатеричной строки я получаю числа.
{"connected":"3.4kVA","fedFrom":"PANEL 'EHE1' & ATS-EM","grounding":"ground bus","id":{"leastSignificantBits":-5323841289984462261,"mostSignificantBits":-8515942329042973684},
Если вы прокрутите страницу, вы увидите, что UUID с именем id представлен в виде пары чисел, а не в виде шестнадцатеричной строки:
"id":{"leastSignificantBits":-5323841289984462261,"mostSignificantBits":-8515942329042973684}
Есть ли способ заставить привязку JSON вести себя так, как привязка XML? Мне нужна шестнадцатеричная строка, а не пара 64-битных чисел.
И, конечно, это маршалированное значение должно работать, когда оно не маршалируется, повторно гидратируется в объект Java.
@Philipp UUID также не является типом данных, известным в XML. Просто позвонив в java.util.UUID::toString, вы сделаете свою работу. Тем не менее, JSON-B изо всех сил пытается сгенерировать пару 64-битных чисел.
Что ж, вы можете назвать это «не с дороги» или нет, но с точки зрения JSON-B UUID - это просто объект (неизвестного типа), который имеет два атрибута (longs), которые JSON-B сериализует в два атрибута, которые вы обратите внимание на ваш вывод: leastSignificantBits и mostSignificantBits. Кстати. у других преобразователей JSON была / есть такая же проблема, например, GSON: github.com/google/gson/issues/79




В спецификации JSON-B не упоминается тип UUID, поэтому реализация зависит от того, предоставляет ли он (де) сериализатор из коробки. Однако, если вы используете Eclipse Yasson (JSON-B ref impl), он по умолчанию предоставляет сериализатор UUID (de). Я не уверен, что другие подразумеваемые JSON-B (например, Apache Johnzon) предоставляют по умолчанию.
Если вы используете Yasson, я бы рекомендовал открыть ошибку на их репозиторий на GitHub, потому что это должно работать.
Если вы используете реализацию 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 делает это под прикрытием), вы можете аннотировать поле / метод для использования адаптера:
public class Panel {
@JsonbTypeAdapter(MyUUIDAdapter.class)
public UUID id;
}
UUIDне является поддерживаемым типом JSON-B, поэтому вам, вероятно, придется реализовать свой собственный адаптер или сериализатор / десериализатор (json-b.net/users-guide.html).