Почему @XmlJavaTypeAdapter в корневом объекте не работает с Marshaller.marshal в JDK 8?JAVA

Программисты JAVA общаются здесь
Anonymous
Почему @XmlJavaTypeAdapter в корневом объекте не работает с Marshaller.marshal в JDK 8?

Сообщение Anonymous »

В продолжение предыдущего вопроса (Как правильно использовать XmlAdapter?).
После решения моего решения с помощью fastxml мне стало любопытно, почему jaxb не работает. По этой причине я подделал исходный код. Вот мое открытие.
Прежде всего, я нашел место, где возникла ошибка, отслеживая маршал. Метод, вызвавший ошибку: com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot. Причина ошибки в том, что tagName имеет значение null и нет аннотации XmlRootElement.
Я пытался найти время присвоения значения tagName и обнаружил, что оно было присвоено при вызове JAXBContext.newInstance.
По своей сути он использует отражение для вызова com.sun.xml.internal.bind.v2.ContextFactory.createContext, а затем создает экземпляр JAXBContextImpl, вызывая JAXBContextImpl.JAXBContextBuilder.build. В конструкторе JAXBContextImpl вызывается getTypeInfoSet. Внутри этого метода объект типа RuntimeModelBuilder с именем builder вызывает getTypeInfo. Через несколько уровней вызовов он в конечном итоге вызывает com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getClassInfo, где выполняются внутренние проверки. Поскольку это первое создание и обычный Java Bean, далее будет вызываться createClassInfo.
В конструкторе com.sun.xml.internal.bind.v2.model.impl.ClassInfoImpl он анализирует имя элемента с помощью метода parseElementName. Если этот класс не имеет аннотации XmlRootElement.class, он будет возвращать значение null напрямую, elementName будет использоваться для принятия значения null.
Когда вызов getTypeInfoSet заканчивается и входит в цикл for, подготовленный для обычного Java-компонента (то есть третий цикл for), он получит или создаст экземпляр com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl, вызвав метод getOrCreate. Когда я ввожу этот метод и далее вхожу в конструктор com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl, он присваивает значение tagName, вызывая ci.isElement(ci имеет тип RuntimeClassInfo), чтобы проверить его истинность. Когда оно ложно, tagName имеет значение null.
А в методе isElement выполняется проверка, имеет ли elementName значение null.
Я использую версию jdk8u472-b08.
Вопрос
  • В процессе отладки кажется, что я это сделал не нашел никакой обработки для адаптера, возможно, потому, что не заметил этого из-за отсутствия навыков.
  • Если кто-то успешно использовал JAXB, не могли бы вы поделиться исходным кодом?
  • Если в процессе отладки, который я описал выше, есть какие-либо упущения или ошибки, не стесняйтесь указать на них.
Ниже приведены мои тестовые коды.

Вернуться в «JAVA»