12 KiB
12 KiB
자바의 Jackson에서 XML과 JSR-310(Java Time API) 관련 기능을 다루는 글을 작성하겠습니다. Jackson은 기본적으로 JSON 처리를 위한 라이브러리지만, jackson-dataformat-xml 모듈을 통해 XML 데이터를 처리할 수 있으며, jackson-datatype-jsr310 모듈을 통해 Java 8의 JSR-310 날짜/시간 API(LocalDate, LocalDateTime 등)를 지원합니다. 이들 모듈은 JSON 처리와 유사한 방식으로 동작하지만, XML 구조나 JSR-310 데이터 타입에 특화된 어노테이션과 설정이 필요합니다.
아래에서는 XML과 JSR-310 관련 주요 어노테이션을 표로 정리한 뒤, 각 어노테이션에 대한 설명과 예시를 상세히 다루겠습니다.
Jackson XML 및 JSR-310 관련 주요 어노테이션 표
XML 관련 어노테이션 (jackson-dataformat-xml)
| 어노테이션 | 설명 |
|---|---|
@JacksonXmlRootElement |
XML 루트 요소의 이름과 네임스페이스를 지정 |
@JacksonXmlProperty |
XML 요소나 속성의 이름과 네임스페이스를 지정하며, 속성 여부를 설정 |
@JacksonXmlElementWrapper |
컬렉션 필드를 감싸는 XML 요소를 지정 |
@JacksonXmlText |
필드를 XML 요소의 텍스트 콘텐츠로 직렬화 |
@JacksonXmlCData |
필드를 XML의 CDATA 섹션으로 직렬화 |
JSR-310 관련 어노테이션 (jackson-datatype-jsr310)
| 어노테이션 | 설명 |
|---|---|
@JsonFormat |
JSR-310 날짜/시간 객체의 직렬화 형식을 지정 (패턴, 시간대 등) |
@JsonSerialize |
JSR-310 객체를 커스터마이즈된 직렬화 방식으로 처리 |
@JsonDeserialize |
JSR-310 객체를 커스터마이즈된 역직렬화 방식으로 처리 |
프로젝트 설정
XML과 JSR-310 기능을 사용하려면 pom.xml에 다음 의존성을 추가해야 합니다:
<!-- Jackson XML 지원 -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.17.0</version>
</dependency>
<!-- Jackson JSR-310 지원 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.17.0</version>
</dependency>
각 어노테이션 상세 설명 및 예시
XML 관련 어노테이션
1. @JacksonXmlRootElement
- 설명: XML 문서의 루트 요소 이름을 지정하며, 네임스페이스를 설정할 수 있습니다.
- 예시:
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
@JacksonXmlRootElement(localName = "person", namespace = "http://example.com")
public class Person {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
public class Main {
public static void main(String[] args) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
Person person = new Person();
person.setName("홍길동");
String xml = xmlMapper.writeValueAsString(person);
System.out.println(xml);
}
}
// 출력: <person xmlns="http://example.com"><name>홍길동</name></person>
2. @JacksonXmlProperty
- 설명: XML 요소나 속성의 이름을 지정하고, 속성으로 직렬화할지 여부를 설정합니다.
- 예시:
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class Person {
@JacksonXmlProperty(localName = "fullName")
private String name;
@JacksonXmlProperty(isAttribute = true)
private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
public class Main {
public static void main(String[] args) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
Person person = new Person();
person.setName("김영희");
person.setAge(25);
String xml = xmlMapper.writeValueAsString(person);
System.out.println(xml);
}
}
// 출력: <Person age="25"><fullName>김영희</fullName></Person>
3. @JacksonXmlElementWrapper
- 설명: 컬렉션 필드를 감싸는 XML 요소를 지정합니다.
- 예시:
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.util.Arrays;
import java.util.List;
public class Person {
@JacksonXmlElementWrapper(localName = "hobbies")
@JacksonXmlProperty(localName = "hobby")
private List<String> hobbies;
public List<String> getHobbies() { return hobbies; }
public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; }
}
public class Main {
public static void main(String[] args) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
Person person = new Person();
person.setHobbies(Arrays.asList("축구", "게임"));
String xml = xmlMapper.writeValueAsString(person);
System.out.println(xml);
}
}
// 출력: <Person><hobbies><hobby>축구</hobby><hobby>게임</hobby></hobbies></Person>
4. @JacksonXmlText
- 설명: 필드를 XML 요소의 텍스트 콘텐츠로 직렬화합니다.
- 예시:
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class Note {
@JacksonXmlText
private String content;
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
}
public class Main {
public static void main(String[] args) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
Note note = new Note();
note.setContent("안녕하세요");
String xml = xmlMapper.writeValueAsString(note);
System.out.println(xml);
}
}
// 출력: <Note>안녕하세요</Note>
5. @JacksonXmlCData
- 설명: 필드를 CDATA 섹션으로 감싸서 직렬화합니다. HTML 태그 등 특수 문자를 포함할 때 유용합니다.
- 예시:
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class Message {
@JacksonXmlProperty(localName = "text")
@JacksonXmlCData
private String content;
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
}
public class Main {
public static void main(String[] args) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
Message message = new Message();
message.setContent("<b>중요</b>");
String xml = xmlMapper.writeValueAsString(message);
System.out.println(xml);
}
}
// 출력: <Message><text><![CDATA[<b>중요</b>]]></text></Message>
JSR-310 관련 어노테이션
1. @JsonFormat
- 설명: JSR-310 날짜/시간 객체의 직렬화 형식을 지정합니다.
pattern속성을 사용하여 원하는 포맷을 정의합니다. - 예시:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.LocalDate;
public class Event {
@JsonFormat(pattern = "yyyy/MM/dd")
private LocalDate date;
public LocalDate getDate() { return date; }
public void setDate(LocalDate date) { this.date = date; }
}
public class Main {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
Event event = new Event();
event.setDate(LocalDate.of(2025, 2, 27));
String json = mapper.writeValueAsString(event);
System.out.println(json);
}
}
// 출력: {"date":"2025/02/27"}
2. @JsonSerialize
- 설명: JSR-310 객체를 사용자 정의 직렬화 방식으로 처리합니다.
JavaTimeModule과 함께 커스터마이징할 때 유용합니다. - 예시:
import com.fasterxml.jackson.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Event {
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate date;
public LocalDate getDate() { return date; }
public void setDate(LocalDate date) { this.date = date; }
}
public class Main {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
Event event = new Event();
event.setDate(LocalDate.of(2025, 2, 27));
String json = mapper.writeValueAsString(event);
System.out.println(json);
}
}
// 출력: {"date":"2025-02-27"} (기본 ISO 포맷)
3. @JsonDeserialize
- 설명: JSR-310 객체를 사용자 정의 역직렬화 방식으로 처리합니다.
- 예시:
import com.fasterxml.jackson.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import java.time.LocalDate;
public class Event {
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate date;
public LocalDate getDate() { return date; }
public void setDate(LocalDate date) { this.date = date; }
}
public class Main {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
String json = "{\"date\":\"2025-02-27\"}";
Event event = mapper.readValue(json, Event.class);
System.out.println(event.getDate());
}
}
// 출력: 2025-02-27
추가 설정 및 주의사항
- XML 처리:
XmlMapper를 사용하여 XML을 직렬화/역직렬화하며, JSON과 달리 계층적 구조를 잘 표현해야 합니다.XmlMapper xmlMapper = new XmlMapper(); - JSR-310 모듈 등록:
JavaTimeModule을ObjectMapper에 등록해야 JSR-310 타입이 기본적으로 지원됩니다.ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule());
결론
Jackson의 XML 및 JSR-310 지원은 JSON 처리 능력을 확장하여 다양한 데이터 형식을 다룰 수 있게 해줍니다. XML 관련 어노테이션은 XML의 요소, 속성, 텍스트를 세밀히 제어하며, JSR-310 관련 어노테이션은 날짜/시간 데이터의 직렬화 형식을 사용자 정의할 수 있게 합니다. 프로젝트에서 이를 활용하려면 적절한 모듈 의존성을 추가하고, XmlMapper 또는 ObjectMapper를 올바르게 설정하는 것이 중요합니다.
추가 질문이 있다면 언제든 물어보세요!