JAXB:Isn';不使用@XmlJavaTypeAdapter就不能使用XmlAdapter吗?
我能否将一堆JAXB:Isn';不使用@XmlJavaTypeAdapter就不能使用XmlAdapter吗?,java,jaxb,adapter,Java,Jaxb,Adapter,我能否将一堆XmlAdapter注册到Marshaller|解组器,这样我就不需要在每个字段上指定@XmlJavaTypeAdapter,因为它的类型本机不支持JAXB 我觉得有点像 顺便说一句,someMarshaller.setAdapter(…)似乎什么都不做。这是一个很好的问题 简而言之,在封送器/解封器上使用setAdapter并不意味着不必使用@XmlJavaTypeAdapter @XmlRootElement(name="event") @XmlType(name="") pub
XmlAdapter
注册到Marshaller
|解组器
,这样我就不需要在每个字段上指定@XmlJavaTypeAdapter
,因为它的类型本机不支持JAXB
我觉得有点像
顺便说一句,
someMarshaller.setAdapter(…)
似乎什么都不做。这是一个很好的问题
简而言之,在封送器/解封器上使用setAdapter
并不意味着不必使用@XmlJavaTypeAdapter
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
// @XmlJavaTypeAdapter(UserAdapter.class)
protected User performedBy;
}
让我用一个假设(但有效!)的场景来解释这一点
考虑在web应用程序中,以具有以下模式的xml形式获取事件:
<xs:element name="event" >
<xs:complexType>
<xs:sequence>
<!-- Avoiding other elements for concentrating on our adapter -->
<xs:element name="performedBy" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
现在应用程序已经有了一个名为User
的bean,它维护详细的
有关用户的信息
public class User {
private String id;
private String firstName;
private String lastName;
..
}
请注意,您的JAXB上下文不知道这个用户。
为了简单起见,我们将User作为POJO,但它可以是任何有效的Java类
应用程序架构师想要的是Event
的performedBy
应该表示为User
获取全部细节
这里是@XmlJavaTypeAdapter出现的地方
JAXBContext知道performedBy
是xs:string
,但它必须表示为
用户
在Java内存中
修改后的模型如下所示:
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
@XmlJavaTypeAdapter(UserAdapter.class)
protected User performedBy;
}
UserAdapter.java:
public class UserAdapter extends XmlAdapter<String, User> {
public String marshal(User boundType) throws Exception {
..
}
public User unmarshal(String valueType) throws Exception {
..
}
}
setAdapter
方法在Marshaller
和Unmarshaller
注:
marshaller/unmarshaller上的setAdapter
并不意味着您不必使用@XmlJavaTypeAdapter
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
// @XmlJavaTypeAdapter(UserAdapter.class)
protected User performedBy;
}
如果省略这个JAXB运行时,就不知道用户是绑定类型&值类型是其他类型。它将尝试按原样封送用户
&u将以错误的xml结束
(如果启用,则验证失败)
虽然我们采用了一种场景,其中适配器必须带有参数,因此
使用setAdapter
方法
还有一些先进的用法,在中,即使您没有默认的arg构造函数,但仍然提供了适配器的实例
可能此适配器配置了数据,封送/解封操作正在使用该数据
您可以使用package-info.java
这就是所谓的“包级别”
例如:
将package-info.java放在要封送/解封的类所在的包中
假设您有一个类mypackage.model.a和一个适配器CalendarAdapter在mypackage.adapter中。
在mypackage.model中声明一个package-info.java文件,其中包含:
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(value = CalendarAdapter.class, type = Calendar.class)
})
package mypackage.model;
import java.util.Calendar;
import mypackage.adapter.CalendarAdapter;
类A中Calendar类型的所有字段都将使用CalendarAdapter封送或取消封送
您可以在那里找到有用的信息:
所以简短的回答是否定的。如果不使用@xmlJavaTypeAdapter注释,就不能使用XmlAdapter
public class Test {
public static void main(String... args) {
JAXBContext context = JAXBContext.getInstance(Event.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
UserContext userContext = null; // fetch it from some where
unmarshaller.setAdapter(UserAdapter.class, new UserAdapter(userContext));
Event event = (Event) unmarshaller.unmarshal(..);
}
}
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
// @XmlJavaTypeAdapter(UserAdapter.class)
protected User performedBy;
}
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(value = CalendarAdapter.class, type = Calendar.class)
})
package mypackage.model;
import java.util.Calendar;
import mypackage.adapter.CalendarAdapter;