자바의 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`에 다음 의존성을 추가해야 합니다: ```xml com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.17.0 com.fasterxml.jackson.datatype jackson-datatype-jsr310 2.17.0 ``` --- ### 각 어노테이션 상세 설명 및 예시 #### XML 관련 어노테이션 ##### 1. `@JacksonXmlRootElement` - **설명**: XML 문서의 루트 요소 이름을 지정하며, 네임스페이스를 설정할 수 있습니다. - **예시**: ```java 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); } } // 출력: 홍길동 ``` ##### 2. `@JacksonXmlProperty` - **설명**: XML 요소나 속성의 이름을 지정하고, 속성으로 직렬화할지 여부를 설정합니다. - **예시**: ```java 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); } } // 출력: 김영희 ``` ##### 3. `@JacksonXmlElementWrapper` - **설명**: 컬렉션 필드를 감싸는 XML 요소를 지정합니다. - **예시**: ```java 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 hobbies; public List getHobbies() { return hobbies; } public void setHobbies(List 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); } } // 출력: 축구게임 ``` ##### 4. `@JacksonXmlText` - **설명**: 필드를 XML 요소의 텍스트 콘텐츠로 직렬화합니다. - **예시**: ```java 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); } } // 출력: 안녕하세요 ``` ##### 5. `@JacksonXmlCData` - **설명**: 필드를 CDATA 섹션으로 감싸서 직렬화합니다. HTML 태그 등 특수 문자를 포함할 때 유용합니다. - **예시**: ```java 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("중요"); String xml = xmlMapper.writeValueAsString(message); System.out.println(xml); } } // 출력: 중요]]> ``` --- #### JSR-310 관련 어노테이션 ##### 1. `@JsonFormat` - **설명**: JSR-310 날짜/시간 객체의 직렬화 형식을 지정합니다. `pattern` 속성을 사용하여 원하는 포맷을 정의합니다. - **예시**: ```java 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`과 함께 커스터마이징할 때 유용합니다. - **예시**: ```java 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 객체를 사용자 정의 역직렬화 방식으로 처리합니다. - **예시**: ```java 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 ``` --- ### 추가 설정 및 주의사항 1. **XML 처리**: `XmlMapper`를 사용하여 XML을 직렬화/역직렬화하며, JSON과 달리 계층적 구조를 잘 표현해야 합니다. ```java XmlMapper xmlMapper = new XmlMapper(); ``` 2. **JSR-310 모듈 등록**: `JavaTimeModule`을 `ObjectMapper`에 등록해야 JSR-310 타입이 기본적으로 지원됩니다. ```java ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); ``` --- ### 결론 Jackson의 XML 및 JSR-310 지원은 JSON 처리 능력을 확장하여 다양한 데이터 형식을 다룰 수 있게 해줍니다. XML 관련 어노테이션은 XML의 요소, 속성, 텍스트를 세밀히 제어하며, JSR-310 관련 어노테이션은 날짜/시간 데이터의 직렬화 형식을 사용자 정의할 수 있게 합니다. 프로젝트에서 이를 활용하려면 적절한 모듈 의존성을 추가하고, `XmlMapper` 또는 `ObjectMapper`를 올바르게 설정하는 것이 중요합니다. 추가 질문이 있다면 언제든 물어보세요!