1. 개요

이 사용방법(예제)는 Jackson ObjectMapper 클래스 를 이해하고 Java 개체를 JSON으로 직렬화하고 JSON 문자열을 Java 개체로 역직렬화하는 방법 에 중점을 둡니다 .

일반적으로 Jackson 라이브러리에 대해 더 많이 이해하려면 Jackson Tutorial 을 시작하는 것이 좋습니다.

2. 의존성

먼저 다음 의존성을 pom.xml에 추가해 보겠습니다 .

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.1</version>
</dependency>

이 의존성은 또한 클래스 경로에 다음 라이브러리를 전이적으로 추가합니다.

  1. 잭슨 어노테이션
  2. 잭슨 코어

jackson-databind 에는 항상 Maven 중앙 저장소의 최신 버전을 사용하십시오 .

3. ObjectMapper를 사용한 읽기 및 쓰기

기본적인 읽기 및 쓰기 작업부터 시작하겠습니다.

ObjectMapper 의 간단한 readValue API 는 좋은 진입점입니다. JSON 콘텐츠를 Java 객체로 구문 분석하거나 역직렬화하는 데 사용할 수 있습니다.

또한 쓰기 측면 에서 writeValue API를 사용하여 모든 Java 객체를 JSON 출력으로 직렬화 할 수 있습니다 .

이 기사 전체에서 직렬화 또는 역직렬화할 개체로 두 개의 필드가 있는 다음 Car 클래스를 사용합니다 .

public class Car {

    private String color;
    private String type;

    // standard getters setters
}

3.1. 자바 객체를 JSON으로

ObjectMapper 클래스 writeValue 메소드를 사용하여 Java 객체를 JSON으로 직렬화하는 첫 번째 예를 살펴보겠습니다 .

ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car("yellow", "renault");
objectMapper.writeValue(new File("target/car.json"), car);

파일에서 위의 출력은 다음과 같습니다.

{"color":"yellow","type":"renault"}

ObjectMapper 클래스 writeValueAsStringwriteValueAsBytes 메소드 는 Java 객체에서 JSON을 생성하고 생성된 JSON을 문자열 또는 바이트 배열로 반환합니다.

String carAsString = objectMapper.writeValueAsString(car);

3.2. JSON을 자바 객체로

다음은 ObjectMapper 클래스를 사용하여 JSON 문자열을 Java 객체로 변환하는 간단한 예입니다 .

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
Car car = objectMapper.readValue(json, Car.class);	

readValue () 함수는 또한 JSON 문자열을 포함하는 파일로서 다른 형태의 입력을 받아 들인다 :

Car car = objectMapper.readValue(new File("src/test/resources/json_car.json"), Car.class);

또는 URL:

Car car = 
  objectMapper.readValue(new URL("file:src/test/resources/json_car.json"), Car.class);

3.3. JSON에서 Jackson JsonNode로

또는 JSON을 JsonNode 객체 로 구문 분석 하고 특정 노드에서 데이터를 검색하는 데 사용할 수 있습니다 .

String json = "{ \"color\" : \"Black\", \"type\" : \"FIAT\" }";
JsonNode jsonNode = objectMapper.readTree(json);
String color = jsonNode.get("color").asText();
// Output: color -> Black

3.4. JSON 배열 문자열에서 Java List 만들기

TypeReference를 사용하여 배열 형태의 JSON을 Java 객체 List으로 구문 분석할 수 있습니다 .

String jsonCarArray = 
  "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
List<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});

3.5. JSON 문자열에서 자바 맵 생성

마찬가지로 JSON을 Java Map 으로 구문 분석할 수 있습니다 .

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
Map<String, Object> map 
  = objectMapper.readValue(json, new TypeReference<Map<String,Object>>(){});

4. 고급 기능

Jackson 라이브러리의 가장 큰 장점 중 하나는 고도로 사용자 정의 가능한 직렬화 및 역직렬화 프로세스입니다.

이 섹션에서는 입력 또는 출력 JSON 응답이 응답을 생성하거나 소비하는 객체와 다를 수 있는 몇 가지 고급 기능을 살펴보겠습니다.

4.1. 직렬화 또는 역직렬화 기능 구성

JSON 객체를 Java 클래스로 변환하는 동안 JSON 문자열에 일부 새 필드가 있는 경우 기본 프로세스에서 예외가 발생합니다.

String jsonString 
  = "{ \"color\" : \"Black\", \"type\" : \"Fiat\", \"year\" : \"1970\" }";

클래스 Car에 대한 Java 객체에 대한 기본 구문 분석 프로세스의 위 예제에서 JSON 문자열 UnrecognizedPropertyException 예외를 발생시킵니다.

configure 메소드를 통해 기본 프로세스를 확장하여 새 필드를 무시할 수 있습니다 .

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Car car = objectMapper.readValue(jsonString, Car.class);

JsonNode jsonNodeRoot = objectMapper.readTree(jsonString);
JsonNode jsonNodeYear = jsonNodeRoot.get("year");
String year = jsonNodeYear.asText();

또 다른 옵션은 FAIL_ON_NULL_FOR_PRIMITIVES 를 기반으로 하며 이는 기본 값에 대한 null 값이 허용 되는지 여부를 정의합니다 .

objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);

마찬가지로 FAIL_ON_NUMBERS_FOR_ENUM 은 열거형 값을 숫자로 직렬화/역직렬화할 수 있는지 여부를 제어합니다.

objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);

공식 사이트 에서 직렬화 및 역직렬화 기능의 전체 List을 찾을 수 있습니다 .

4.2. 사용자 지정 직렬 변환기 또는 역직렬 변환기 만들기

ObjectMapper 클래스 의 또 다른 필수 기능은 사용자 지정 직렬 변환기직렬 변환기 를 등록하는 기능 입니다.

사용자 지정 직렬 변환기 및 역직렬 변환기는 입력 또는 출력 JSON 응답이 직렬화 또는 역직렬화되어야 하는 Java 클래스와 구조가 다른 상황에서 매우 유용합니다.

다음은 사용자 지정 JSON 직렬 변환기의 예입니다 .

public class CustomCarSerializer extends StdSerializer<Car> {
    
    public CustomCarSerializer() {
        this(null);
    }

    public CustomCarSerializer(Class<Car> t) {
        super(t);
    }

    @Override
    public void serialize(
      Car car, JsonGenerator jsonGenerator, SerializerProvider serializer) {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField("car_brand", car.getType());
        jsonGenerator.writeEndObject();
    }
}

이 사용자 지정 직렬 변환기는 다음과 같이 호출할 수 있습니다.

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = 
  new SimpleModule("CustomCarSerializer", new Version(1, 0, 0, null, null, null));
module.addSerializer(Car.class, new CustomCarSerializer());
mapper.registerModule(module);
Car car = new Car("yellow", "renault");
String carJson = mapper.writeValueAsString(car);

다음 은 클라이언트 측 에서 Car 가 (JSON 출력으로) 보이는 것입니다.

var carJson = {"car_brand":"renault"}

다음 은 사용자 지정 JSON deserializer 의 예입니다 .

public class CustomCarDeserializer extends StdDeserializer<Car> {
    
    public CustomCarDeserializer() {
        this(null);
    }

    public CustomCarDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Car deserialize(JsonParser parser, DeserializationContext deserializer) {
        Car car = new Car();
        ObjectCodec codec = parser.getCodec();
        JsonNode node = codec.readTree(parser);
        
        // try catch block
        JsonNode colorNode = node.get("color");
        String color = colorNode.asText();
        car.setColor(color);
        return car;
    }
}

이 사용자 지정 디시리얼라이저는 다음과 같은 방식으로 호출할 수 있습니다.

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
ObjectMapper mapper = new ObjectMapper();
SimpleModule module =
  new SimpleModule("CustomCarDeserializer", new Version(1, 0, 0, null, null, null));
module.addDeserializer(Car.class, new CustomCarDeserializer());
mapper.registerModule(module);
Car car = mapper.readValue(json, Car.class);

4.3. 날짜 형식 처리

java.util.Date 의 기본 직렬화는 숫자, 즉 epoch 타임스탬프(UTC로 1970년 1월 1일 이후의 밀리초 수)를 생성합니다. 그러나 이것은 사람이 읽을 수 있는 것이 아니며 사람이 읽을 수 있는 형식으로 표시하려면 추가 변환이 필요합니다.

datePurchased 속성을 사용하여 Request 클래스 안에 지금까지 사용한 Car 인스턴스를 래핑해 보겠습니다 .

public class Request 
{
    private Car car;
    private Date datePurchased;

    // standard getters setters
}

날짜의 문자열 형식을 제어하고 예를 들어 yyyy-MM-dd HH:mm az 로 설정하려면 다음 스니펫을 고려하십시오.

ObjectMapper objectMapper = new ObjectMapper();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
objectMapper.setDateFormat(df);
String carAsString = objectMapper.writeValueAsString(request);
// output: {"car":{"color":"yellow","type":"renault"},"datePurchased":"2016-07-03 11:43 AM CEST"}

Jackson으로 날짜를 직렬화하는 방법에 대해 자세히 알아보려면 자세한 내용을 읽어 보세요 .

4.4. 컬렉션 처리

DeserializationFeature 클래스를 통해 사용할 수 있는 작지만 유용한 또 다른 기능 은 JSON 배열 응답에서 원하는 컬렉션 유형을 생성하는 기능입니다.

예를 들어 결과를 배열로 생성할 수 있습니다.

String jsonCarArray = 
  "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
Car[] cars = objectMapper.readValue(jsonCarArray, Car[].class);
// print cars

또는 List으로 :

String jsonCarArray = 
  "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
List<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});
// print cars

Jackson을 사용하여 컬렉션을 처리하는 방법에 대한 자세한 내용은 여기에서 확인할 수 있습니다 .

5. 결론

Jackson은 Java용 견고하고 성숙한 JSON 직렬화/역직렬화 라이브러리입니다. ObjectMapper의 API는 많은 유연성과 JSON 응답 객체를 구문 분석하고 생성하는 간단한 방법을 제공합니다. 이 기사에서는 라이브러리를 인기 있게 만드는 주요 기능에 대해 설명했습니다.

기사와 함께 제공되는 소스 코드는 GitHub 에서 찾을 수 있습니다 .

Jackson footer banner