Jackson ObjectMapper 소개

1. 개요

이 튜토리얼은 Jackson ObjectMapper 클래스 를 이해하고 Java 객체를 JSON으로 직렬화하고 JSON 문자열을 Java 객체로 역 직렬화하는 방법 에 중점을 둡니다 .

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

2. 종속성

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

 com.fasterxml.jackson.core jackson-databind 2.11.1  

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

  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. Java 개체를 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에서 Java 개체로

다음은 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 목록 생성

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

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

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

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

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

4. 고급 기능

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

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

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

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

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

The JSON string in the above example in the default parsing process to the Java object for the Class Car will result in the UnrecognizedPropertyException exception.

Through the configure method, we can extend the default process to ignore the new fields:

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(); 

Yet another option is based on the FAIL_ON_NULL_FOR_PRIMITIVES, which defines if the null values for primitive values are allowed:

objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false); 

Similarly, FAIL_ON_NUMBERS_FOR_ENUM controls if enum values are allowed to be serialized/deserialized as numbers:

objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);

You can find the comprehensive list of serialization and deserialization features on the official site.

4.2. Creating Custom Serializer or Deserializer

Another essential feature of the ObjectMapper class is the ability to register a custom serializer and deserializer.

Custom serializers and deserializers are very useful in situations where the input or the output JSON response is different in structure than the Java class into which it must be serialized or deserialized.

Below is an example of a custom JSON serializer:

public class CustomCarSerializer extends StdSerializer { public CustomCarSerializer() { this(null); } public CustomCarSerializer(Class t) { super(t); } @Override public void serialize( Car car, JsonGenerator jsonGenerator, SerializerProvider serializer) { jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("car_brand", car.getType()); jsonGenerator.writeEndObject(); } } 

This custom serializer can be invoked like this:

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); 

Here's what the Car looks like (as JSON output) on the client side:

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

And here's an example of a custom JSON deserializer:

public class CustomCarDeserializer extends StdDeserializer { 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; } } 

This custom deserializer can be invoked in this way:

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. Handling Date Formats

The default serialization of java.util.Date produces a number, i.e., epoch timestamp (number of milliseconds since January 1, 1970, UTC). But this is not very human readable and requires further conversion to be displayed in a human-readable format.

Let's wrap the Car instance we used so far inside the Request class with the datePurchased property:

public class Request { private Car car; private Date datePurchased; // standard getters setters } 

To control the String format of a date and set it to, e.g., yyyy-MM-dd HH:mm a z, consider the following snippet:

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"} 

To learn more about serializing dates with Jackson, read our more in-depth write-up.

4.4. Handling Collections

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

또는 목록으로 :

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

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

5. 결론

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

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