Jackson은 Java 개체를 다양한 텍스트 형식으로 직렬화/역직렬화하는 데 널리 사용되는 라이브러리입니다. ObjectMapper 클래스 JSON 형식으로 작업하는 라이브러리의 주요 방법입니다. 다른 형식의 경우 자손( XmlMapper , YAMLMapper ) 이 있습니다 . 상속 덕분에 단일 인터페이스를 통해 일관된 방식으로 모든 형식으로 작업할 수 있습니다.

jar 파일 다운로드

예제를 살펴보기 전에 Jackson jar 파일을 다운로드하여 IntelliJ IDEA의 프로젝트에 연결해야 합니다. jackson-databind 의 예를 들어 필요한 파일을 검색하는 방법을 살펴보겠습니다.

  1. Maven 리포지토리 웹 사이트 로 이동합니다 .

  2. 검색 상자에 " jackson-databind "를 입력합니다. 다음을 얻을 수 있습니다.

  3. 첫 번째 검색 결과는 우리가 관심 있는 것입니다. 링크를 따라가십시오.

  4. 경우에 따라 프로젝트의 다른 구성 요소와의 호환성을 보장하기 위해 특정 버전의 라이브러리가 필요할 수 있습니다. 최신 버전이 작동해야 합니다(이 강의를 작성할 당시에는 2.13.2.2임). 링크를 따르십시오.

  5. 열리는 페이지에서 "번들" 링크를 원합니다.

  6. 이 링크를 사용하여 jar 파일을 다운로드하십시오 .

유사한 절차에 따라 나머지 필요한 jar 파일을 찾아 다운로드할 수 있습니다.

필요한 모든 파일을 다운로드한 후 IntelliJ IDEA의 프로젝트에 연결합니다.

  1. 프로젝트 설정을 엽니다( Ctrl+Alt+Shift+S 키 조합으로 수행할 수 있음).

  2. 라이브러리 로 이동합니다 .

  3. +를 누른 다음 "Java"를 누릅니다. 다운로드한 파일을 모두 선택합니다. 우리가 끝내야 할 것은 다음과 같습니다.

  4. 이것으로 준비 작업을 마칩니다. 이제 ObjectMapper를 실제로 사용해 볼 수 있습니다 .

JSON으로 직렬화

먼저 일부 개체를 JSON으로 직렬화합니다.

import com.fasterxml.jackson.databind.ObjectMapper;

class Book {
	public String title;
	public String author;
	public int pages;
}

public class Solution {
	public static void main(String[] args) throws Exception {
    	Book book = new Book();
    	book.title = "Good Omens";
    	book.author = "Pratchett T., Gaiman N.";
    	book.pages = 383;

    	ObjectMapper mapper = new ObjectMapper();
    	String jsonBook = mapper.writeValueAsString(book);
    	System.out.println(jsonBook);
	}
}

main을 실행하면 다음과 같은 결과가 나타납니다.

{"title":"좋은 징조","author":"Pratchett T., Gaiman N.","pages":383}

ObjectMapper 에는 많은 고급 설정이 있습니다. 그 중 하나를 사용하여 JSON 문자열을 더 읽기 쉽게 만들어 보겠습니다. 생성 후객체 매퍼다음 명령문을 실행합니다.

mapper.enable(SerializationFeature.INDENT_OUTPUT);

출력의 정보는 동일하게 유지되지만 이제 들여쓰기와 줄 바꿈이 있습니다.

{
  "제목": "좋은 징조",
  "저자": "Pratchett T., Gaiman N.",
 "페이지": 383
}

JSON에서 역직렬화

이제 반대 작업을 수행해 보겠습니다. 문자열을 개체로 deserialize합니다. 프로그램이 수행하는 작업을 볼 수 있도록 Book 클래스 에서 toString 메서드를 재정의해 보겠습니다 .

@Override
public String toString() {
	return "Book{" +
        	"title='" + title + '\'' +
        	", author='" + author + '\'' +
        	", pages=" + pages +
        	'}';
}

그리고 우리는 main 메서드 에서 다음을 수행할 것입니다 .

public static void main(String[] args) throws Exception {
	String jsonString = "{\"title\":\"Good Omens\",\"author\":\"Pratchett T., Gaiman N.\",\"pages\":383}";
	Book book = new ObjectMapper().readValue(jsonString, Book.class);
	System.out.println(book);
}

산출:

도서{제목='좋은 징조', 저자='Pratchett T., Gaiman N.', 페이지=383}

readValue 메서드는 오버로드되어 파일, 링크, 다양한 입력 스트림 등을 취하는 많은 변형이 있습니다. 단순성을 위해 예제에서는 JSON 문자열을 허용하는 변형을 사용합니다 .

위에서 언급했듯이 ObjectMapper 에는 많은 설정이 있습니다. 그 중 몇 가지를 살펴보겠습니다.

알 수 없는 속성 무시

JSON 문자열에 Book 클래스 에 없는 속성이 있는 상황을 고려하십시오 .

public static void main(String[] args) throws Exception {
	String jsonString = """
        	{
          	"title" : "Good Omens",
          	"author" : "Pratchett T., Gaiman N.",
          	"pages" : 383,
          	"unknown property" : 42
        	}""";
	ObjectMapper mapper = new ObjectMapper();
	Book book = mapper.readValue(jsonString, Book.class);
	System.out.println(book);
}

이 코드를 실행하면 UnrecognizedPropertyException 이 발생합니다 . 이것은 기본 동작이지만 변경할 수 있습니다.

ObjectMapper mapper =
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

만들 때객체 매퍼개체에 대해서는 configure 메서드를 사용하여 해당 설정을 false 로 설정합니다 . configure 메서드는 호출된 개체를 수정한 다음 동일한 개체를 반환하므로 다른 방식으로 이 호출을 수행할 수 있습니다 .

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

기능면에서 이 표기법은 이전 표기법과 같습니다.

이제 기본 메서드를 실행하면 deserialization이 성공하고 unknown 속성이 무시됩니다.

편리한 주석

Jackson은 모든 종류의 방식으로 직렬화 프로세스를 사용자 정의할 수 있는 몇 가지 주석을 제공합니다. 가장 유용한 몇 가지를 살펴보겠습니다.

@JsonIgnore — 이 주석은 직렬화/역직렬화 중에 무시해야 하는 요소 위에 배치됩니다.

class Book {
	public String title;
	@JsonIgnore
	public String author;
	public int pages;
}

여기서작가필드는 직렬화 중에 결과 JSON에 포함되지 않습니다. 역직렬화 시,작가필드는 JSON에 다른 값이 있더라도 기본값(null)을 가져옵니다.

@JsonFormat — 이 주석을 사용하면 직렬화된 데이터의 형식을 설정할 수 있습니다. Book 클래스 에 Date 필드를 하나 더 추가해 보겠습니다 .

class Book {
	public String title;
	public String author;
	public int pages;
	public Date createdDate = new Date();
}

직렬화 후 다음 JSON을 얻습니다.

 {
  "title": "Good Omens",
  "author": "Pratchett T., Gaiman N.",
  "pages": 383,
  "createdDate": 1649330880788
}

보시다시피 날짜가 숫자로 연재되었습니다. 주석을 추가하고 형식을 설정합니다.

class Book {
	public String title;
	public String author;
	public int pages;
	@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
	public Date createdDate = new Date();
}

이제 직렬화 결과는 다음과 같습니다.

{
  "title": "Good Omens",
  "author": "Pratchett T., Gaiman N.",
  "pages": 383,
  "createdDate": "2022-04-07"
}

@JsonProperty — 이 주석을 사용하면 직렬화된 필드를 나타내는 속성의 이름을 변경할 수 있습니다. 이 주석으로 메소드를 표시할 수도 있습니다. 그렇게 하면 직렬화 중에 반환 값이 JSON 속성으로 변환됩니다.

class Book {
	@JsonProperty("name")
	public String title;
	public String author;
	public int pages;

	@JsonProperty("quotedTitle")
	public String getQuotedTitle() {
    	    return "\"" + title + "\"";
	}
}

직렬화 결과:

{
  "저자": "Pratchett T., Gaiman N.",
  "페이지": 383,
  "이름": "좋은 징조",
  "quotedTitle": "\"좋은 징조\""
}

@JsonInclude — 이 주석을 사용하여 직렬화할 필드에 대해 충족해야 하는 조건을 지정할 수 있습니다. 개별 필드 또는 전체 클래스에 적용할 수 있습니다. 먼저 초기화되지 않은 필드가 있는 개체를 직렬화해 보겠습니다.

public class Solution {
	public static void main(String[] args) throws Exception {
    		Book book = new Book();

    		ObjectMapper mapper = new ObjectMapper();
    		mapper.enable(SerializationFeature.INDENT_OUTPUT);
    		String jsonBook = mapper.writeValueAsString(book);
    		System.out.println(jsonBook);
	}
}

직렬화 결과:

{
  "제목": null,
  "저자": null,
  "페이지": 0
}

주석을 추가하면 다음과 같습니다.

@JsonInclude(JsonInclude.Include.NON_NULL)
class Book {
	public String title;
	public String author;
	public int pages;
}

그런 다음 다음 결과를 얻습니다.

{
  "페이지" : 0
}

이제 null 인 필드는 직렬화되지 않습니다.

@JsonPropertyOrder — 이 주석을 사용하면 필드가 직렬화되는 순서를 설정할 수 있습니다.

@JsonPropertyOrder({"author", "title", "pages"})
class Book {
	public String title;
	public String author;
	public int pages;
}

직렬화 결과:

{
  "저자": "Pratchett T., Gaiman N.",
  "제목": "Good Omens",
  "페이지": 383
}

지금은 주석을 사용하는 방법만 기억하세요. 이 모듈을 마치면 이들에 대해 더 잘 알게 되고 고유한 주석을 만들 수도 있습니다.

XML의 직렬화 및 역직렬화

XML로 직렬화해야 하는 경우 동일한 설정과 주석을 모두 사용할 수 있습니다. 유일한 차이점은매퍼 개체:

public static void main(String[] args) throws Exception {
	Book book = new Book();
	book.title = "Good Omens";
	book.author = "Pratchett T., Gaiman N.";
	book.pages = 383;

	ObjectMapper mapper = new XmlMapper();
	mapper.enable(SerializationFeature.INDENT_OUTPUT);
	String xmlBook = mapper.writeValueAsString(book);
	System.out.println(xmlBook);
}

산출:

 <Book>
  <title>Good Omens</title>
  <author>Pratchett T., Gaiman N.</author>
  <pages>383</pages>
</Book>

XML 역직렬화:

public static void main(String[] args) throws Exception {
   String xmlString = """
            <Book>
             <title>Good Omens</title>
             <author>Pratchett T., Gaiman N.</author>
             <pages>383</pages>
           </Book>""";
   ObjectMapper mapper = new XmlMapper();
   Book book = mapper.readValue(xmlString, Book.class);
   System.out.println(book);
}

YAML의 직렬화 및 역직렬화

XML을 처리하는 것과 동일한 방식으로 YAML을 처리합니다.

public static void main(String[] args) throws Exception {
	Book book = new Book();
	book.title = "Good Omens";
	book.author = "Pratchett T., Gaiman N.";
	book.pages = 383;

	ObjectMapper mapper = new YAMLMapper();
	mapper.enable(SerializationFeature.INDENT_OUTPUT);
	String yamlBook = mapper.writeValueAsString(book);
	System.out.println(yamlBook);
}

산출:

---
제목: "Good Omens"
저자: "Pratchett T., Gaiman N."
페이지: 383

YAML 역직렬화:

public static void main(String[] args) throws Exception {
   String yamlString = """
           ---
           title: "Good Omens"
           author: "Pratchett T., Gaiman N."
           pages: 383""";
   ObjectMapper mapper = new YAMLMapper();
   Book book = mapper.readValue(yamlString, Book.class);
   System.out.println(book);
}