이것은 아주 좋은 질문입니다!
짧은 대답은 마샬에 setAdapter
를 사용 없는 것을/Unmarshaller에 당신이 @XmlJavaTypeAdapter
을 사용할 필요가 없습니다 것을 의미하지 않는다이다.
가설 (아직 유효한!) 시나리오로 설명해 드리겠습니다.
웹 응용 프로그램에서 고려, 하나의 스키마 다음 XML을 갖는 형태로 이벤트를 가져옵니다 : 이제
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
protected String performedBy;
}
응용 프로그램이에
<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
이라는 빈을 가지고있다. 이 User
이 당신의 JAXB 컨텍스트에 알려지지 않은 것을
는
public class User {
private String id;
private String firstName;
private String lastName;
..
}
참고. 간단히하기 위해 사용자는 POJO로 설정되어 있지만 유효한 Java 클래스가 될 수 있습니다. 응용 프로그램 설계자가 원하는 무엇
이다 User
은 자세한 내용을 얻을으로의 performedBy
가 표현되어야 Event
. @XmlJavaTypeAdapter이
있다 JAXBContext가 xs:string
으로 performedBy
에 대한 인식 그림으로 오는 곳 여기
이지만, 자바에서 메모리에
User
로 표현되어야한다.
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
@XmlJavaTypeAdapter(UserAdapter.class)
protected User performedBy;
}
UserAdapter :
수정 된 모델처럼 보인다.자바 :
public class UserAdapter extends XmlAdapter<String, User> {
public String marshal(User boundType) throws Exception {
..
}
public User unmarshal(String valueType) throws Exception {
..
}
}
어댑터의 정의는 말한다 -
- BoundType이 (Memeory 표현에서) 사용자
- 치 형이 String의이 (데이터 유형 JAXB 컨텍스트가 알고있다)이다
다시 질문하기 -
다소 중복되었습니다.
현재 SomeMarshaller.setAdapter (...)는 아무 것도하지 않는 것 같습니다.
마샬링/언 마샬링을 성공적으로 수행하려면 어댑터에 UserContext라는 클래스가 필요하다고 생각해보십시오.
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);
}
}
이제 UserAdapter가 Instace를 어떻게 가져 오나요? 인스턴스화있어 반면 하나가 항상 공급해야 좋은 디자인으로 ..
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);
}
}
그러나 JAXB 런타임은 인자없는 생성자 어댑터를 받아 들일 수 .. 는 (물론 JAXBContext에 응용 프로그램 특정 모델에 대해 알고하지 않습니다)
그래서 고맙게도 옵션이 있습니다 : D
당신은 오히려 자신의 자신에 의해 그것을 복귀하려고보다 UserAdapter
의 당신의 unmarshaller
사용하는 지정된 인스턴스를 알 수 있습니다.
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
방법은 모두 Marshaller
& Unmarshaller
참고로 볼 수 있습니다 :
마샬에
setAdapter
/Unmarshaller에 당신이 @XmlJavaTypeAdapter
을 사용하지 않는다는 것을 의미하지 않는다.
@XmlRootElement(name="event")
@XmlType(name="")
public class Event {
@XmlElement(required=true)
// @XmlJavaTypeAdapter(UserAdapter.class)
protected User performedBy;
}
당신이 JAXB 런타임이 사용자가 & 값 유형이 다른 것을 당신의 바운드 형이라고 단서가 없습니다 생략하면. (사용하는 경우 또는 유효성 검사 실패) 우리는 어댑터가 인수로 요구되는 시나리오, 따라서 사용 setAdapter
방법을 가지고 있지만 u는 잘못된 XML 을 가진
을 종료합니다 &이기 때문에 그것은 User
를 마샬링하려고합니다.
일부 adavanced 용도가, 심지어 경우에 당신이 인수 없음의 생성자를 기본 않습니다이 경우도있다, 그러나 당신은 정렬 화/비 정렬 화 조작이 사용
이 어댑터가 데이터로 구성되어있다 어댑터의 인스턴스를 제공 !
을 ** 그래서 짧은 대답은 NO입니다 ** 당신은 @XmlJavaTypeAdapter 주석을 사용하지 않고 (때문에) XmlAdapter를 사용할 수 없습니다. – user1128134