[RabbitMQ] JSON Message Format 사용하기 - 2
이번 글에서는 RabbitMQ에서 사용하는 JSON Message Format을 Customize 해보도록 하겠습니다.
1. Customize JSON Format
앞선 글에선 Jackson의 ObjectMapper를 사용해 Employee Entity를 JSON String 형식으로 변경할 수 있었습니다.
Employee
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private String employeeId;
private String name;
private LocalDate birthDate;
}
기본적으로 Jackson은 Default로 구현되어있는 serialize() 메서드를 참고해 아래와 같이 Serialize를 수행합니다.
{
"employeeId":"minho",
"name":"test",
"birthDate": {
"year":2019,
"month":"DECEMBER",
"dayOfMonth":30,
"monthValue":12,
"dayOfYear":364,
"leapYear":false,
"dayOfWeek":"MONDAY",
"era":"CE",
"chronology":{
"id":"ISO",
"calendarType":"iso8601"
}
}
}
"employeeId"와 "name"의 JSON key값은 Entity의 필드명으로 value 값은 사용자가 입력한 "minho"와 "test"로 Serialize된 것을 확인할 수 있습니다.
하지만, birthDate는 지나치게 복잡하게 Serialize 되어있는 것을 확인할 수 있습니다. Spring 내부적으로 LocalDate 객체의 serialize() 값이 위 처럼 구현되어있기 때문에 위와 같이 Serialize 된 것입니다.
사용자는 Customize 기능을 이용해 위와 같은 Default JSON Format을 변경할 수 있습니다.
2. @JsonProperty
@JsonProperty를 사용하면 JSON Format의 Key값을 변경할 수 있습니다.
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
@JsonProperty("employee_id")
private String employeeId;
private String name;
@JsonProperty("birth_date")
private LocalDate birthDate;
}
위와 같이 변경 후 Message를 열어보면, 아래와 같이 JSON String의 key값이 변경된 것을 확인할 수 있습니다.
✔ 변경전 : employeeId / birthDate
✔ 변경후 : employee_id / birth_date
{
"employee_id":"minho",
"name":"test",
"birth_date": {
"year":2019,
"month":"DECEMBER",
"dayOfMonth":30,
"monthValue":12,
"dayOfYear":364,
"leapYear":false,
"dayOfWeek":"MONDAY",
"era":"CE",
"chronology":{
"id":"ISO",
"calendarType":"iso8601"
}
}
}
3. @JsonSerialize
@JsonSerialize를 사용하면 JSON Format의 Serialize 형식을 변경할 수 있습니다.
@JsonSerialize 사용해 LocalDate의 Serialize 값에서 불필요한 부분을 제거하고 필요한 부분만 Serialize 해보겠습니다.
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private String employeeId;
private String name;
@JsonSerialize(using = CustomLocalDateSerializer.class)
private LocalDate birthDate;
}
@JsonSerialize(using = CustomLocalDateSerializer.class)을 입력해 앞으로 birthDate는 Serialize할 때 Default로 구현되어있는 값 대신 CustomLocalDateSerializer에 구현한 serialize 메서드를 사용하도록 지정합니다.
CustomLocalDateSerializer의 구조는 아래와 같습니다.
public class CustomLocalDateSerializer extends StdSerializer<LocalDate> {
private static final long serialVersionUID = 1L;
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MMM-dd");
public CustomLocalDateSerializer() {
this(null);
}
public CustomLocalDateSerializer(Class<LocalDate> t) {
super(t);
}
@Override
public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider arg2)
throws IOException, JsonProcessingException {
gen.writeString(formatter.format(value));
}
}
위의 Custom Serializer를 이용하면 복잡한 Local Date의 Serialize 값을 "yyyy-MMM-dd" 형식으로 변경해 사용할 수 있습니다.
Producer Application을 실행시킨뒤 Message를 확인해보면 아래와 같이 LocalDate가 Serialize된 값이 변경된것을 확인할 수 있습니다.
4. @JsonDeserialize
만약 @JsonSerialize를 사용해서 JSON Stirng의 Format을 변경했다면, 반대로 Consumer에서는 @JsonDeserialize를 사용해 JSON String 값을 이전 객체의 모양으로 적절히 Deserialize 해야합니다.
만약 이를 구현하지 않는다면, Consumer에서는 해당 JSON String 값을 이전의 객체모양으로 Parse할 수 없습니다.
Consumer쪽 Entity에는 아래와 같이 Deserialize에 사용할 Custom Class를 지정해주면 됩니다.
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private String employeeId;
private String name;
@JsonDeserialize(using = CustomLocalDateDeserializer.class)
private LocalDate birthDate;
}
CustomLocalDateDeserializer의 구조는 아래와 같습니다.
public class CustomLocalDateDeserializer extends StdDeserializer<LocalDate> {
private static final long serialVersionUID = 1L;
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MMM-dd");
public CustomLocalDateDeserializer() {
super(LocalDate.class);
}
@Override
public LocalDate deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return LocalDate.parse(parser.readValueAs(String.class), formatter);
}
}
5. 정리
✔ Jackson의 ObjectMapper 클래스를 사용하면 "Entity to JSON" / "JSON to Entity"가 가능하다.
✔ Producer에서 Customize한 Serialize Class를 사용해 JSON String Format을 변경한다면, Consumer에서는 적절한 Deserialize Class를 사용해 JSON Stirng을 기존의 Entity로 Deserialize 해야 한다.
참고 자료 : https://www.udemy.com/course/rabbitmq-java-spring-boot-for-system-integration/
'Spring Cloud > RabbitMQ' 카테고리의 다른 글
[RabbitMQ] Publisher API (0) | 2021.11.03 |
---|---|
[RabbitMQ] Retry Mechanism (0) | 2021.11.03 |
[RabbitMQ] Dead Letter Exchange & TTL(Time To Live) (0) | 2021.11.01 |
[RabbtiMQ] Exchange (Message broker) (0) | 2021.11.01 |
[RabbitMQ] JSON Message Format 사용하기 - 1 (0) | 2021.11.01 |
[RabbitMQ] Scheduling 사용하기 (0) | 2021.11.01 |
[RabbitMQ] Spring boot 기본 사용법 (0) | 2021.11.01 |
[RabbitMQ] Message System을 사용하는 이유 (0) | 2021.11.01 |