spring feign 을 사용 중이었는데 response 로 json 을 받아와 feign 내부에서 jackson 을 통해 Object 로 매핑해준다.
해당 json 데이터는 원래 DB 에 들어있던 json string 이었다.
"data": \"{\""id"\":\""temp"\"}\"
그래서 처음에는 매핑받는 클래스에서 다음과 같이 inner 클래스로 해당 json string 까지 알아서 매핑되도록 했었다.
public class Parent {
...
private Data data;
...
public class Data {
private String id;
...
}
}
그런데 파싱을 할 수 없다고 오류가 발생했다. (오류는 기억이 안나는데 재현하기 귀찮음) json 에 data 키를 매핑 할 수 없다고 에러를 뱉었는데, inner class 가 아닌 String 으로 받으면 또 잘 받아왔다.
물론 다음과 같이 데이터가 들어갔다.
String data = "\"{"\"id"\":\""temp"\"}\""
그래서 한참을 끙끙대다가 deserializer
클래스를 따로 구현해서 @JsonDeserialize
어노테이션을 이용해 매핑되도록 하려고 했다.
백슬래쉬까지 같이 읽을 수 있는 jackson 라이브러리의 ObjectMapper
와 JsonNode
를 사용해서 매핑시켜주었다.
public class DataDeserializer extends JsonDeserializer<Data> {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public Data deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
JsonNode jsonNode = objectMapper.readTree(jsonParser.getText());
return objectMapper.treeToValue(jsonNode, Data.class);
}
}
조금 불필요한 코드가 추가됐지만 매핑을 해주기 위해 어쩔 수 없었다. ㅠㅠ
JsonNode
를 사용하지 않고 아래의 코드로 매핑을 해줬는 대도 에러 발생;;
return objectMapper.readValue(jsonParser.getText(), Data.class)
그래서 백슬래쉬를 removeAll
로 지워주고 하면 되지 않을까? 했지만 결국 오류 뱉음.
그래서 \"
로 없애줄까? 했는데 이것도 안됨.
결국 그래서 JsonNode
로 변환해준 뒤에 treeToValue()
메소드를 이용해서 해결했다.
참고로 아래의 코드처럼 @JsonDeserialize
어노테이션 달아주는 것 잊지말자
public class Parent {
...
@JsonDeserialize(using = HistoryDeserializer.class)
private Data data;
...
public class Data {
private String id;
...
}
}