자바에서 Gson과 JAXB로 JSON을 XML로 변환하기: 단계별 가이드
JSON이란?
JSON(JavaScript Object Notation)은 키-값 쌍을 사용하는 가볍고 언어에 독립적인 데이터 형식입니다. 데이터 교환에 널리 사용되며 파일이나 데이터베이스에 쉽게 저장할 수 있습니다.
{ "username": "guru99user", "email": "guru99user@mail.com" }
주요 특징:
- 중괄호 {}로 감싸집니다.
- 키와 문자열 값은 따옴표로 묶습니다.
- 쌍은 쉼표로 구분합니다.
- 키는 문자, 숫자, 밑줄 사용 가능하며 숫자로 시작하거나 공백을 포함할 수 없습니다.
XML이란?
XML(eXtensible Markup Language)은 W3C 표준 구조화 데이터 형식입니다. HTML과 달리 순수 데이터 형식이며 시각적 렌더링이 없습니다. 사용자 정의 태그를 허용해 시스템 간 데이터 교환에 이상적입니다.
일반적인 노드 구조:
<node>content</node>
XML 파일 최상단에는 버전 선언이 필요합니다:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
Gson이란?
Gson은 자바 객체를 JSON으로 직렬화하고 JSON을 자바 객체로 역직렬화하는 자바 라이브러리입니다. v1.6부터 JsonReader와 JsonWriter를 통한 스트리밍도 지원합니다.
스트리밍 작성자 예시:
JsonWriter writer = new JsonWriter(new FileWriter(filePath));
writer.beginObject();
writer.name("key").value("value");
writer.endObject();
writer.close();
JAXB란?
JAXB(Java Architecture for XML Binding)는 어노테이션을 사용해 자바 클래스를 XML에 매핑합니다. 마샬링(자바 → XML)과 언마샬링(XML → 자바)을 지원합니다.
주요 어노테이션:
@XmlRootElement – 루트 XML 요소 정의
@XmlElementWrapper – 컬렉션 래핑
@XmlElement – 필드를 XML 요소에 매핑
@XmlAttribute – 필드를 XML 속성에 매핑
프로젝트 설정
- IDE(예: Eclipse)에서 자바 프로젝트 생성
- 프로젝트명을 XmlToJsonExample으로 지정
data/input 폴더 생성 후 sample.xml과 sample.json 배치
- Gson 2.8.5를 빌드 경로에 추가
- JAXB API 추가(자바 8에 보통 포함)
샘플 데이터
역할과 인원을 포함한 부서의 XML 표현:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <root> <department> <roles> <role id="1"> <position>head</position> <salary>10k</salary> </role> <role id="2"> <position>manager</position> <salary>8k</salary> </role> <role id="3"> <position>employee</position> <salary>5k</salary> </role> </roles> <persons> <person id="1"> <name>Red</name> <role>1</role> </person> <person id="2"> <name>Green</name> <role>2</role> </person> <person id="3"> <name>Blue</name> <role>2</role> </person> <person id="4"> <name>Yellow</name> <role>3</role> </person> <person id="5"> <name>Brown</name> <role>3</role> </person> </persons> </department> </root>
동등한 JSON 구조:
{ "roles": [ {"id":"1","position":"head","salary":"10k","persons":[{"id":"1","name":"Red"}]}, {"id":"2","position":"manager","salary":"8k","persons":[{"id":"2","name":"Green"},{"id":"3","name":"Blue"}]}, {"id":"3","position":"employee","salary":"5k","persons":[{"id":"4","name":"Yellow"},{"id":"5","name":"Brown"}]} ] }
자바 모델 클래스
model 패키지에 다음 POJO들을 정의하세요:
/* Role.java */
@XmlRootElement(name = "role")
public class Role {
private String id, position, salary;
// @XmlAttribute/@XmlElement 어노테이션이 붙은 getter, setter
}
/* Person.java */
@XmlRootElement(name = "person")
public class Person {
private String id, name, role;
// @XmlAttribute/@XmlElement 어노테이션이 붙은 getter, setter
}
/* Department.java */
@XmlRootElement(name = "department")
public class Department {
private List<Role> roles;
private List<Person> persons;
// @XmlElementWrapper/@XmlElement가 붙은 getter/setter
}
/* XMLModel.java */
@XmlRootElement(name = "root")
public class XMLModel {
private Department department;
// @XmlElement가 붙은 getter/setter
}
XML을 자바 객체로 언마샬링 (JAXB)
public XMLModel getObjectFromXmlFile(String path) throws JAXBException {
File file = new File(path);
JAXBContext ctx = JAXBContext.newInstance(XMLModel.class);
Unmarshaller um = ctx.createUnmarshaller();
return (XMLModel) um.unmarshal(file);
}
자바 객체를 XML로 마샬링 (JAXB)
public void parseObjectToXml(String path, XMLModel model) throws JAXBException, IOException {
JAXBContext ctx = JAXBContext.newInstance(XMLModel.class);
Marshaller m = ctx.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(model, new FileOutputStream(path));
}
자바 객체를 JSON으로 직렬화 (Gson)
public void writeDataToJsonFile(String path, List<Role> roles, List<Person> persons) throws IOException {
JsonWriter writer = new JsonWriter(new FileWriter(path));
writer.setIndent(" ");
writer.beginObject();
writer.name("roles").beginArray();
for (Role r : roles) {
writer.beginObject();
writer.name("id").value(r.getId());
writer.name("position").value(r.getPosition());
writer.name("salary").value(r.getSalary());
writer.name("persons").beginArray();
for (Person p : persons)
if (p.getRole().equals(r.getId())) {
writer.beginObject();
writer.name("id").value(p.getId());
writer.name("name").value(p.getName());
writer.endObject();
}
writer.endArray();
writer.endObject();
}
writer.endArray();
writer.endObject();
writer.close();
}
JSON을 자바 객체로 역직렬화 (Gson)
public void getDataFromJsonFile(String path, List<Role> roles, List<Person> persons) throws IOException {
JsonReader reader = new JsonReader(new FileReader(path));
reader.beginObject();
while (reader.hasNext()) {
String rootName = reader.nextName();
if ("roles".equals(rootName)) {
reader.beginArray();
while (reader.hasNext()) {
reader.beginObject();
Role r = new Role();
while (reader.hasNext()) {
String key = reader.nextName();
switch (key) {
case "id": r.setId(reader.nextString()); break;
case "position": r.setPosition(reader.nextString()); break;
case "salary": r.setSalary(reader.nextString()); break;
case "persons":
reader.beginArray();
while (reader.hasNext()) {
reader.beginObject();
Person p = new Person();
p.setRole(r.getId());
while (reader.hasNext()) {
String pKey = reader.nextName();
if ("id".equals(pKey)) p.setId(reader.nextString());
else if ("name".equals(pKey)) p.setName(reader.nextString());
}
persons.add(p);
reader.endObject();
}
reader.endArray();
break;
}
}
roles.add(r);
reader.endObject();
}
reader.endArray();
}
}
reader.endObject();
reader.close();
}
전체 변환 워크플로
- JAXB를 사용해
sample.xml을 XMLModel로 언마샬링
- 결과 자바 객체를 Gson으로
sample.json에 직렬화
sample.json을 다시 자바 객체로 역직렬화
- 해당 객체들을 새 XML 파일로 마샬링
결론
이 가이드는 깔끔한 2단계 변환 파이프라인을 보여줍니다: JAXB가 XML ↔ 자바를, Gson이 JSON ↔ 자바를 담당합니다. 두 라이브러리를 결합하면 자바 애플리케이션에서 포맷 간 데이터를 신뢰성 있게 변환할 수 있습니다.