"그렇게 빠르지 않아, 젊은이! 두 가지 교훈이 더 있어!"

"두 개? 와우. 글쎄요. 당신 자신의 멋짐을 향상시키기 위해 무엇을 하지 않겠습니까! 나는 귀를 기울이고 있습니다."

"JSON과 같은 XML은 서로 다른 프로그램과 컴퓨터 간에 데이터를 전달할 때 자주 사용됩니다. 그리고 XML로 작업할 때 Java 프로그래머의 삶을 크게 단순화하는 여러 프레임워크가 있습니다. 오늘은 그 중 하나를 소개하겠습니다."

"JAXB는 XML 작업을 위한 탁월한 다목적 프레임워크입니다."

JAXB-1

"JAXB는 JDK의 일부이므로 별도로 다운로드할 필요가 없습니다."

"먼저 사용 방법의 예를 보여 드린 다음 분석하겠습니다. 예를 들면 다음과 같습니다."

개체를 XML로 변환
public static void main(String[] args) throws JAXBException
{
 // Create an object to be serialized into XML
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // Create a Marshaller object that will perform the serialization
 JAXBContext context = JAXBContext.newInstance(Cat.class);
 Marshaller marshaller = context.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 // And here's the serialization itself:
 marshaller.marshal(cat, writer);

 // Convert everything written to the StringWriter
 String result = writer.toString();
 System.out.println(result);
}
개체가 XML로 변환되는 클래스
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}
직렬화 결과 및 화면 출력:
<cat> 
<name> Missy </name> 
<age> 5 </age> 
<weight> 4 </weight> 
</cat>

"어떤 이유에서인지 이 코드는 JSON 직렬화를 생각나게 합니다. 동일한 주석이지만 JSON은 ObjectMapper를 사용했으며 이것은 Context 및 Marshaller를 사용합니다."

"네. 정말 비슷합니다. Jackson은 JAXB를 모델로 했습니다. 하지만 JAXB도 어딘가에서 복사되었습니다. 처음부터 천재적인 것을 발명할 수는 없습니다."

"그런 것 같습니다."

"알겠습니다. 다음과 같이 진행됩니다."

"4-7행에서 Cat 개체를 만들고 데이터로 채웁니다."

"10번째 줄에서 Writer 개체를 만들어 결과를 기록합니다."

"13번째 줄에서 '컨텍스트'를 만듭니다. 이것은 ObjectMapper와 유사하지만 두 개의 추가 자식 개체가 생성됩니다. Marshaller 는 직렬화용이고 Unmarshaller 는 역직렬화용입니다. Jackson과 약간의 차이가 있지만 근본적으로 다르지 않다."

"14행에서 Marshaller 개체를 만듭니다 . 마샬링은 직렬화와 동의어입니다."

"15행에서 ​​FORMATTED_OUTPUT 속성을 TRUE로 설정했습니다. 이렇게 하면 결과에 줄 바꿈과 공백이 추가되어 코드를 사람이 읽을 수 있고 한 줄에 모든 텍스트가 표시되지 않습니다."

"17행에서 개체를 직렬화합니다."

"20-21행에서 직렬화 결과를 화면에 표시합니다."

"@XmlType(name = 'cat&') 및 @XmlRootElement 주석은 무엇입니까?"

" @XmlRootElement는 이 개체가 XML 요소의 '트리의 루트'가 될 수 있음을 나타냅니다. 즉, 최상위 수준 요소가 될 수 있으며 다른 모든 요소를 ​​포함할 수 있습니다."

" @XmlType(name = 'cat')은 클래스가 JAXB 직렬화에 관련되어 있음을 나타내며 이 클래스에 대한 XML 태그의 이름도 지정합니다."

"좋아, 이제 XML 역직렬화의 예를 보여주겠다."

XML에서 개체 변환
public static void main(String[] args) throws JAXBException
{
 String xmldata = "<cat><name>Missy</name><age>5</age><weight>4</weight></cat>";
 StringReader reader = new StringReader(xmldata);

 JAXBContext context = JAXBContext.newInstance(Cat.class);
 Unmarshaller unmarshaller = context.createUnmarshaller();

 Cat cat = (Cat) unmarshaller.unmarshal(reader);
}
개체가 XML에서 역직렬화되는 클래스
@XmlType(name = "cat")
@XmlRootElement
public class Cat
{
 public String name;
 public int age;
 public int weight;

 public Cat()
 {
 }
}

"모든 것이 잭슨과 거의 같습니다. 하지만 만일의 경우를 대비하여 여기서 진행되는 모든 것을 설명하겠습니다."

"3번째 줄에서 역직렬화할 XML을 저장하는 문자열을 전달합니다 ."

"4행에서 XML 문자열을 StringReader 로 래핑합니다 ."

"6행에서 클래스 목록을 전달하는 JAXB 컨텍스트를 만듭니다 ."

"7행에서 역직렬화를 수행할 개체인 Unmarshaller를 만듭니다 ."

"라인 9에서 판독기 개체에서 XML을 역직렬화하고 Cat 개체를 가져옵니다."

"이제 모든 것이 거의 명백해 보입니다. 하지만 몇 시간 전에 어떻게 작동하는지 알아내려고 머리를 쥐어짜고 있었습니다."

"당신이 더 똑똑해지면 항상 그런 일이 일어납니다. 복잡한 것이 단순해집니다."

"나는 점점 더 똑똑해지고 있다고? 나는 그것에 대해 기뻐할 수밖에 없다."

"좋습니다. JAXB 직렬화 결과를 제어하는 ​​데 사용할 수 있는 주석 목록은 다음과 같습니다."

JAXB 주석 설명
@XmlElement(이름) 들판 근처에 배치.
필드는 XML 요소에 저장됩니다.
태그의 이름을 설정할 수 있습니다.
@XmlAttribute(이름) 들판 근처에 배치.
필드는 XML 속성으로 저장됩니다!
속성의 이름을 설정할 수 있습니다.
@XmlElementWrapper(nillable = true) 들판 근처에 배치.
요소 그룹에 대해 '래퍼 태그'를 설정할 수 있습니다.
@XmlType 클래스 근처에 배치.
기본 생성자가 전용인 경우 객체 생성 방법을 지정할 수 있습니다.
@XmlJavaTypeAdapter 들판 근처에 배치.
필드를 문자열로 변환할 클래스를 지정할 수 있습니다.

"흥미롭군요! 하지만 이러한 주석을 사용하는 예를 제공할 수 있습니까? 설명은 한 가지이지만 작업 예는 다른 것입니다."

"좋아요. 예를 보여드리겠습니다. JAXB를 사용하면 필드 대신 getter/setter 메서드에 주석을 달 수 있다는 점을 추가하고 싶었습니다."

"내가 약속한 예는 다음과 같습니다."

개체를 XML로 변환
public static void main(String[] args) throws JAXBException
{
 // Create Cat and Zoo objects to be serialized into XML
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 Zoo zoo = new Zoo();
 zoo.animals.add(cat);
 zoo.animals.add(cat);

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // Create a Marshaller object that will perform the serialization
 JAXBContext context = JAXBContext.newInstance(Cat.class, Zoo.class);
 Marshaller marshaller = context.createMarshaller();
 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
 // Here's the serialization itself
 marshaller.marshal(zoo, writer);

 // Convert everything written to the StringWriter into a String
 System.out.println(writer.toString());
}
개체가 XML로 변환되는 클래스
@XmlType(name = "zoo")
@XmlRootElement
public class Zoo
{
 @XmlElementWrapper(name = "wild-animals", nillable = true)
 @XmlElement(name = "tiger")
 public List<Cat> animals = new ArrayList<>();
}

public class Cat
{
 @XmlElement(name = "catname")
 public String name;
 @XmlAttribute(name = "age")
 public int age;
 @XmlAttribute(name = "w")
 public int weight;

 public Cat()
 {
 }
}
직렬화 결과 및 화면 출력:
<zoo> 
<wild-animals> 
<tiger age = "5" w = "4"> 
<catname>Missy</catname> 
</tiger> 
<tiger age = "5" w = "4"> 
<catname>Missy </catname> 
</tiger> 
</wild-animals> 
</zoo>

"이번에는 Cat 개체를 직렬화하는 것이 아니라 Cat 개체 컬렉션을 저장하는 Zoo 개체를 직렬화한다는 점에 유의하십시오."

"고양이 개체가 컬렉션에 두 번 추가되었으므로 XML에 두 번 있습니다."

"컬렉션에는 컬렉션의 모든 요소를 ​​감싸는 자체 ' 야생 동물 ' 태그가 있습니다."

" 연령 및 체중 요소는 연령 및 w w 속성이 되었습니다 ."

" @XmlElement 속성을 사용하여 고양이 태그를 호랑이 태그로 변경했습니다 ."

"17행에 주의를 기울이십시오. 여기서 우리는 두 클래스( ZooCat )를 JAXB 컨텍스트에 전달합니다. 둘 다 직렬화에 관련되어 있기 때문입니다."

"오늘은 매우 흥미로운 날이었습니다. 새로운 정보가 너무 많습니다."

"네. 반갑습니다. 이제 잠시 쉬었다가 계속하겠습니다."