ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Json 파싱시 없는 필드 무시(@JsonIgnoreProperties)
    Spring Framework 2023. 8. 31. 00:01
    728x90

    개요

    API response가 나도 모르게 추가되면 어떻게 될까?

     

    개발을 진행하다 보면 메시지를 받거나, 외부 API응답을 받아올 때 객체가 String형태로 변환되어 해당 형태를 다시 객체로 만들 필요가 있습니다.

    이때 받아오는 필드들이 100개가 있고 나는 여기서 2개만 관심 있는 경우도 종종 있을 수 있습니다.

     

    또는 API가 V1 -> V2로 변경되면서 나도 모르게 메시지의 형식이나 외부 API 응답이 달라지게 되면 어떻게 될까요?

    응답 파싱시 장애가 발생할 수 있습니다.

     

    이럴 때 유용하게 사용할 수 있는 @JsonIgnoreProperties에 대해 알아보고자 합니다.

     

    @JsonIgnoreProperties  JavaDocs 설명

    Annotation that can be used to either suppress serialization of properties (during serialization), or ignore processing of JSON properties read (during deserialization).
    Example:
      // to prevent specified fields from being serialized or deserialized
      // (i.e. not include in JSON output; or being set even if they were included)
      @JsonIgnoreProperties({ "internalId", "secretKey" })
      // To ignore any unknown properties in JSON input without exception:
      @JsonIgnoreProperties(ignoreUnknown=true)
     
    Annotation can be applied both to classes and to properties. If used for both, actual set will be union of all ignorals: that is, you can only add properties to ignore, not remove or override. So you can not remove properties to ignore using per-property annotation.

     

    간단하게 번역해보면 해당 어노테이션은 JSON 프로퍼티의 직렬화/역직렬화를 수행할 때 사용되고 프로퍼티의 처리를 무시하는 데 사용할 수 있습니다.

     

    특정 필드를 지정하는 방법이 있고, 알 수 없는 프로퍼티를 모두 무시할 수도 있습니다.

     

    @JsonIgnoreProperties JavaDocs 설명 - ignoreUnkown

    어노테이션의 ignoreUnown의 필드의 기본값은 false입니다.

    즉, 알 수 없는 프로퍼티를 무시하지 않도록 정의되어 있습니다.

    만약 ignoreUnown 필드의 값을 true로 설정해 주면 예외나 경고 없이 무시됩니다.

     

     

    사용예시

    @JsonIgnoreProperties(ignoreUnknown = true)
    data class MyIgnoreDTO(
      @JsonProperty("col1")
      val col1: String,
      @JsonProperty("col2")
      val col2: String,
      @JsonProperty("col3")
      val col3: String,
    )

    단순히 클래스위에 @JsonIgnoreProperties를 붙여주고 ignoreUnkown 옵션에 true를 주면 됩니다.

    이제 알 수 없는 프로퍼티인 col4, col5 같은 필드가 추가되더라도 예외가 발생하지 않고 잘 변환됩니다.

     

     

    Spring Boot 예시

    @Component
    class JsonParseApplicationRunner(
    	private val objectMapper: ObjectMapper,
    ) : ApplicationRunner {
    	override fun run(args: ApplicationArguments) {
    		println("ApplicationRunner Args: " + Arrays.toString(args.sourceArgs))
    
    		val payload = objectMapper.writeValueAsString(AnotherClass())
    		val parse = objectMapper.readValue(payload, MyIgnoreDTO::class.java)
    		println(parse)
    		//MyIgnoreDTO(col1=col1, col2=col2, col3=col3)
    	}
    }
    
    
    @JsonIgnoreProperties(ignoreUnknown = true)
    data class MyIgnoreDTO(
    	@JsonProperty("col1")
    	val col1: String,
    	@JsonProperty("col2")
    	val col2: String,
    	@JsonProperty("col3")
    	val col3: String,
    )
    
    data class AnotherClass(
    	@JsonProperty("col0")
    	val col0: String = "col0",
    	@JsonProperty("col1")
    	val col1: String = "col1",
    	@JsonProperty("col2")
    	val col2: String = "col2",
    	@JsonProperty("col3")
    	val col3: String = "col3",
    	@JsonProperty("col4")
    	val col4: String = "col4",
    )

    Spring ApplicationRunner를 사용하여 스프링 부트 애플리케이션 구동 시 특정 코드를 실행시킵니다.

    AnthoerClass를 만들어서 Stirng으로 직렬화 한 뒤 MyIgnoreDTO클래스로 역직렬화해 보았습니다.

    col0, col4 프로퍼티에 대해서는 알 수 없지만 역직렬화가 잘 수행되는 것을 확인할 수 있습니다.

     

     

    Spring Boot의 기본설정과 @JsonIgnoreProperties

    Spring Boot에서 기본적으로 지원하는 Jackson의 ObjectMapper에는 알 수 없는 프로터티가 존재할 때 기본적으로 무시합니다.

     

    만약 ObjectMapper를 재정의하거나 의도적으로 알 수 없는 프로터티가 존재할때 예외가 발생하도록 설정되어 있다면 @JsonIgnoreProperties를 활용해보는건 어떨까요?

     

     

    참고자료

    https://fasterxml.github.io/jackson-annotations/javadoc/2.9/com/fasterxml/jackson/annotation/JsonIgnoreProperties.html

     

    JsonIgnoreProperties (Jackson-annotations 2.9.0 API)

    Annotation that can be used to either suppress serialization of properties (during serialization), or ignore processing of JSON properties read (during deserialization). Example: // to prevent specified fields from being serialized or deserialized // (i.e.

    fasterxml.github.io

     

     

     

    댓글

Designed by Tistory.