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>
이 의존성은 또한 클래스 경로에 다음 라이브러리를 전이적으로 추가합니다.
- 잭슨 어노테이션
- 잭슨 코어
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 클래스 의 writeValueAsString 및 writeValueAsBytes 메소드 는 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 응답 객체를 구문 분석하고 생성하는 간단한 방법을 제공합니다. 이 기사에서는 라이브러리를 인기 있게 만드는 주요 기능에 대해 설명했습니다.