Spring Framework/๐Ÿ“› ์—๋Ÿฌ ๊ธฐ๋ก

[๐Ÿ“› Error] JsonParser.Feature.ALLOW_SINGLE_QUOTES

soogoori 2024. 5. 3. 13:26

์–ด๋–ค ์ƒํ™ฉ์ธ์ง€...

์™ธ๋ถ€ API๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์‘๋‹ต ๊ฐ’์„ ๋ฐ›์„ ๋•Œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์ด๋‹ค.

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.core.codec.DecodingException: JSON decoding error: Unexpected character (''' (code 39)): was expecting double-quote to start field name] with root cause 

 

ํ•ด์„ํ•ด๋ณด๋ฉด ์‘๋‹ต ๊ฒฐ๊ณผ๊ฐ€ single quotes์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด๋กœ ํŒŒ์‹ฑํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ ๊ฐ™๋‹ค. 


 

์ฐธ๊ณ ๋กœ ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ์œ„์™€ ๊ฐ™๋‹ค. 

ResponseDto ๊ฐ์ฒด๋กœ ํŒŒ์‹ฑํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ์ œ๋Œ€๋กœ ๋˜์ง€ ์•Š์•˜๋‹ค. 

 

 

 

JsonParser.Feature.ALLOW_SINGLE_QUOTES 

์‘๋‹ต๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒด๋กœ ๋ฐ›์ง€ ์•Š๊ณ , String์œผ๋กœ ๋จผ์ € ๋ฐ›์•˜๋‹ค๊ฐ€ ObjectMapper๋ฅผ ์ด์šฉํ•ด์„œ single quotes๋กœ ํŒŒ์‹ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ™œ์šฉํ•ด๋ดค๋‹ค. 

 

ํ•ด๋‹น ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์€ ๋‹คํ–‰ํžˆ baeldung์— ์ž˜ ๋‚˜์™€์žˆ์—ˆ๋‹ค. 

 

 

 

 

์ฝ”๋“œ ๊ตฌํ˜„

@RequiredArgsConstructor
@Service
@Slf4j
public class WebClientService {

    @Value("${alan.key}")
    private String alanId;
    private final WebClient webClient = WebClient.builder().build();
    private final ObjectMapper objectMapper = new ObjectMapper().configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

    public Flux<AlanResponseDto> getResponse(){
        return webClient.get()
                .uri("https://kdt-api-function.azurewebsites.net/api/v1/question/sse-streaming",
                        uriBuilder -> uriBuilder
                        .queryParam("content", "red")
                        .queryParam("client_id", alanId)
                        .build())
                .retrieve()
                .bodyToFlux(String.class)
                .flatMap(this::parseJsonToResponseDto);
    }

    private Flux<AlanResponseDto> parseJsonToResponseDto(String jsonString){
        try {
            // Parse JSON string to ResponseDto object
            AlanResponseDto responseDto = this.objectMapper.readValue(jsonString, AlanResponseDto.class);
            return Flux.just(responseDto);
        } catch (JsonProcessingException e) {
            // Handle parsing exception
            return Flux.error(e);
        }
    }
}

 

WebClient๋ฅผ ์ƒ์„ฑํ•ด์„œ HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , 

Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ObjectMapper๋ฅผ ์ƒ์„ฑํ•ด JSON ๋ฌธ์ž์—ด์„ AlanResponseDto ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. 

private final ObjectMapper objectMapper = new ObjectMapper().configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); 

Jackson์€ ๊ธฐ๋ณธ์ ์œผ๋กœ JSON ๋ฌธ์ž์—ด์— ํฐ ๋”ฐ์˜ดํ‘œ๋ฅผ ์‚ฌ์šฉํ•ด ๋ฌธ์ž์—ด ๊ฐ’์„ ํ‘œ์‹œํ•˜๋Š”๋ฐ ์ž‘์€ ๋”ฐ์˜ดํ‘œ๋ฅผ ํ—ˆ์šฉํ•˜๋„๋ก ํ•˜์—ฌ ํŒŒ์‹ฑ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ๋ฌธ์ œ ์—†๊ฒŒ๋” ๋งŒ๋“ค์—ˆ๋‹ค. 

 

parseJsonToResponseDto()๋ฉ”์„œ๋“œ๋Š” JSON ๋ฌธ์ž์—ด์„ AlanResponseDto ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. 

AlanResponseDto ๊ฐ์ฒด๋กœ ํŒŒ์‹ฑํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ Flux๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

 

 

 

 

์ฐธ๊ณ ์ž๋ฃŒ

https://www.baeldung.com/jackson-exception