2009-06-05 2 views
81

저는 JAXB를 처음 사용하고 JAXB 2.1.3의 xjc를 사용하여 XML 스키마에서 클래스 세트를 생성했습니다. 내 스키마의 각 요소에 대한 클래스를 생성하는 것 외에도 ObjectFactory 클래스를 만들었습니다.JAXB 2의 ObjectFactory 클래스의 핵심은 무엇입니까?

요소를 직접 인스턴스화하지 못하는 것 같지 않습니다. 예 :

public MyElement createMyElement() { 
    return new MyElement(); 
} 

때문에 거래 내용은 다음과 같습니다

MyElement element = new MyElement(); 

튜토리얼 내가 ObjectFactory.java로 보면, 내가 볼

MyElement element = new ObjectFactory().createMyElement(); 

을 선호하는 것 같다 반면? 왜 나는 ObjectFactory 클래스를 유지하는 것을 괴롭혀 야합니까? 변경된 스키마에서 다시 컴파일하는 경우에도 덮어 쓰기된다고 가정합니다.

답변

56

이전 버전과의 호환성은 유일한 이유는 아니다. :-P

요소의 내용이 가질 수있는 값에 대한 복잡한 제약이있는 복잡한 스키마와 같이 실제 JAXBElement 개체를 만들어야하는 경우가 있습니다. 그들은 손으로 만드는 것이 일반적으로 쉽지 않으므로 create* 방법이 당신을 위해 열심히 노력합니다. 합니다 (XHTML 1.1 스키마) 예 : 유용하지만합니다 (ObjectFactory

ObjectFactory factory = new ObjectFactory(); 
XhtmlHtmlType html = factory.createXhtmlHtmlType(); 
XhtmlHeadType head = factory.createXhtmlHeadType(); 
html.setHead(head); 
XhtmlStyleType style = factory.createXhtmlStyleType(); 
head.getContent().add(factory.createXhtmlHeadTypeStyle(style)); 

처음 세 개의 용도가 불필요한 것으로 간주 될 수있다 :

@XmlElementDecl(namespace = "http://www.w3.org/1999/xhtml", name = "style", scope = XhtmlHeadType.class) 
public JAXBElement<XhtmlStyleType> createXhtmlHeadTypeStyle(XhtmlStyleType value) { 
    return new JAXBElement<XhtmlStyleType>(_XhtmlHeadTypeStyle_QNAME, XhtmlStyleType.class, XhtmlHeadType.class, value); 
} 

이렇게하면 <head> 태그로 <style> 태그를 얻는 방법이다 일관성을 위해), 네 번째는 JAXB를 훨씬 더 쉽게 사용할 수있게 해준다. 매번 손으로 new JAXBElement을 작성하는 이미징!

+0

create *()가 유용한 일을하기 위해 스키마 요소가 필요한 요소 (또는 복잡성)의 예제/참조를 제공 할 수 있습니까? JAXB 예제에서 참조하고있는 스키마 부분을 찾는 데 문제가 있습니다. 내 스키마가 나중에 더 복잡해지면 create *가 나를 위해 그 일부를 처리하는 것이 좋겠지 만 create *는 하위 요소를 자체적으로 만들지 않습니다. –

+0

XHTML 1.1 및 XHTML 모듈화 1.1 타르볼을 사용하면 "SCHEMA"라는 디렉토리를 찾을 수 있습니다. 모든 .xsd 파일을 동일한 디렉토리에 저장하십시오. 일부 .xsd 파일은 http://www.w3.org/2001/xml.xsd도 가져옵니다. xjc를 실행할 때마다 파일을 다운로드하지 않으려면 위치를 적절히 조정해야합니다. [cont] –

+0

[cont] 의 내용을 지정하는 .xsd의 특정 부분은이 경우 xhtml11-model-1.xsd의 xhtml.head.content 그룹 아래에 있습니다. –

8

이전 버전 호환성, 제 생각 엔 ...

http://weblogs.java.net/blog/kohsuke/archive/2005/08/a_story_of_migr.html :

... 더 이상 ObjectFactory.createXYZ. 팩토리 메소드의 문제점 은 체크섬을 던졌습니다. JAXBException. 이제 간단하게 new XYZ()를 수행하면 더 이상 try/catch 블록을 사용할 수 없습니다. (나는 ...이 그 "우리가!? 생각했다" 것들 중 하나입니다, 내가 알고, 알고) ...

34

@Chris가 지적했듯이 스키마가 Java에 정확하게 매핑 될 수 없기 때문에 JAXB는 POJO와 함께 작동하지 않을 수 있습니다. 이 경우 추가 유형 정보를 제공하려면 JAXBElement 랩퍼 오브젝트가 필요합니다.

여기에는 공통점이있는 두 가지 구체적인 예가 있습니다.

  • 당신이 @XmlRootElement 주석이없는 클래스의 객체를 마샬링합니다. 기본적으로 XJC는 일부 요소에만 @XmlRootElement을 생성하고 다른 요소에는 생성하지 않습니다.이것에 대한 정확한 논리는 약간 복잡하지만 XJC가 "simple binding mode"

  • 을 사용하여 XJC에서 더 많은 클래스를 생성하도록 할 수 있습니다. 스키마가 대체 그룹을 사용하는 경우. 이것은 꽤 고급 스키마 사용이지만 XJC는 JAXBElement 래퍼를 많이 사용하여 대체 그룹을 Java로 변환합니다.

그래서 (어떤 이유) JAXBElement 많이 활용할 수있는 XJC 생성 된 개체 모델에서, 당신은 그 JAXBElement 인스턴스를 구성하는 방법이 필요합니다. 생성 된 ObjectFactory은 훨씬 쉬운 방법입니다. 너 수 있습니다 그들 자신을 건설하지만, 그것은 clunky하고 오류가 발생하기 쉬운 경향이 있습니다.

+0

추가 사례를 보내 주셔서 감사합니다. –

+2

와우, 그게 승리의 해답이야. +1 –

+2

또한 3 개월 늦었 어 :) – skaffman

관련 문제