¡Esta es una muy buena pregunta!
La respuesta corta es que no , utilizando setAdapter
en marshaller/unmarshaller no quiere decir que usted no tiene que utilizar @XmlJavaTypeAdapter
.
Déjenme explicar esto con un escenario hipotético (¡pero válido!).
tener en cuenta en una aplicación web, uno va a buscar un evento en forma de XML que tiene la siguiente esquema:
<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>
Equivalente a esto, el modelo se verá así:
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
protected String performedBy;
}
Ahora la aplicación ya tiene un bean llamado User
que mantiene la información detallada sobre el usuario.
public class User {
private String id;
private String firstName;
private String lastName;
..
}
Tenga en cuenta que este User
no se conoce a su contexto JAXB. Para simplificar, tenemos el usuario como POJO, pero puede ser cualquier clase válida de Java.
Lo que quiere es arquitecto de aplicaciones Event
's performedBy
deben estar representados como User
para ganar más detalles.
Aquí es donde entra en el cuadro @XmlJavaTypeAdapter
JAXBContext es consciente de performedBy
como xs:string
, pero tiene que ser representado como User
en la memoria en Java.
modelo modificado se ve así:
@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 {
..
}
}
definición
El adaptador de dice que -
- BoundType es usuario (En representación Memeory)
- ValueType es String (El Contexto tipo de datos JAXB es consciente de)
Regresar a su pregunta -
Me resulta algo redundante.
Por cierto, algunosMarshaller.setAdapter (...) parecen no hacer nada.
Considere que nuestro Adaptador requiere una clase llamada UserContext para organizar/desenmascarar con éxito.
public class UserAdapter extends XmlAdapter<String, User> {
private UserContext userContext;
public String marshal(User boundType) throws Exception {
return boundType.getId();
}
public User unmarshal(String valueType) throws Exception {
return userContext.findUserById(valueType);
}
}
Ahora la pregunta es cómo va a ir a buscar un UserAdapter se instace de UserContext ?? Como un buen diseño siempre se debe suministrarla al tiempo que ha consiguió una instancia ..
public class UserAdapter extends XmlAdapter<String, User> {
private UserContext userContext;
public UserAdapter(UserContext userContext) {
this.userContext = userContext;
}
public String marshal(User boundType) throws Exception {
return boundType.getId();
}
public User unmarshal(String valueType) throws Exception {
return userContext.findUserById(valueType);
}
}
Pero JAXB tiempo de ejecución sólo puede aceptar adaptadores sin-args constructor .. (Obviamente JAXBContext no sabe nada de modelo específico de la aplicación)
Así que por suerte no es una opción: D
Usted puede decirle a su unmarshaller
utilizar instancia dada de UserAdapter
en lugar de la creación de instancias que por su propia cuenta.
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(..);
}
}
setAdapter
método está disponible tanto en Marshaller
& Unmarshaller
Nota:
setAdapter
en marshaller/unmarshaller no quiere decir que usted no tiene que utilizar @XmlJavaTypeAdapter
.
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
// @XmlJavaTypeAdapter(UserAdapter.class)
protected User performedBy;
}
Si se omite este tiempo de ejecución JAXB no tiene ni idea de que su usuario está Tipo Bound & Tipo Valor es otra cosa. Se tratará de reunir User
como es & u será llegar a tener mal xml (o la validación falla si está habilitado)
Si bien hemos tomado un escenario en el que se requiere adaptador para estar con argumentos, por lo tanto, uso setAdapter
método.
Algunos usos adavanced también están allí, donde en incluso si usted tiene defecto sin argumentos del constructor, sin embargo, que proporcionan una instancia del adaptador
mayo de este adaptador está configurado con los datos, que Mariscal/operación unmarshal está utilizando !
** Así respuesta corta es no ** No se puede utilizar sin necesidad de utilizar XmlAdapter anotación @xmlJavaTypeAdapter. – user1128134