簡體   English   中英

如何處理 Spring 啟動中的 UnsupportedMediaTypeException?

[英]How to handle UnsupportedMediaTypeException in Spring Boot?

您好,我正在嘗試通過在 spring 引導中使用 Webclient 來調用 API。

但我有一些問題。

雖然我請求的響應是 json 響應,但當服務器發生錯誤時,服務器會給我一個 xml 響應。

因此,當發生服務器錯誤時,我收到 UnsupportedMediaTypeException 錯誤。

因此,當發生 UnsupportedMediaTypeException 錯誤時,我想制作一個可以向我發送 email 的業務邏輯。

如何處理 UnsupportedMediaTypeException?

下面的代碼是我的 api 調用代碼。

@Override
public void run() {
    //여기서 API를 호출할거임
    DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(BASE_URL); //UriBuilder를 생성하는 옵션을 설정하는 DefaultUriBuilderFactory 인스턴스 생성
    factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY); //encoding 모드 설정

    
    HttpClient client = HttpClient.create()
            .responseTimeout(Duration.ofSeconds(60)); //http response timeout 설정을 60초로 설정함
    
    WebClient wc = WebClient.builder()
            .uriBuilderFactory(factory) //위에서 만든 uri 인코딩 설정으로 uribuilder 설정을 함
            .baseUrl(BASE_URL) //baseURI 설정하고
            .clientConnector(new ReactorClientHttpConnector(client)) //위에서 만든 타임아웃 설정을 적용시키고
            .build(); //빌드한다.
    
    result = new SweatherRootRes();
    
    Mono<SweatherRootRes> response = wc.get()
            .uri(uriBuilder -> uriBuilder.path("/getVilageFcst")
                    .queryParam("serviceKey", swr.getServiceKey())
                    .queryParam("numOfRows", swr.getNumOfRows())
                    .queryParam("pageNo", swr.getPageNo())
                    .queryParam("dataType", swr.getDataType())
                    .queryParam("base_date", swr.getBase_date())
                    .queryParam("base_time", swr.getBase_time())
                    .queryParam("nx", swr.getNx()) //지역정보
                    .queryParam("ny", swr.getNy()) //지역정보
                    .build()) //위 쿼리들로 uri 빌드를 하고
            .retrieve() //http 요청하고
            .onStatus(HttpStatus::is4xxClientError,
                    error -> Mono.error(new RuntimeException("API not found")))
            .onStatus(HttpStatus::is5xxServerError,
                    error -> Mono.error(new RuntimeException("Server is not responding")))
            .bodyToMono(SweatherRootRes.class);//Mono로 값을 받고
    
    //여기서 type mismatch 되는 부분을 찾아야함
    
    //비동기 방식으로 약간 콜백 메소드와 같은 역할을 하는것 같다.그래서  이부분은 api 연결이 성공했을때 들어오는 부분인것 같다.
    response.subscribe(res -> {
        result.setResponse(res.getResponse());
        if(result.getResponse().getBody()!= null) {
            getTemp(result.getResponse().getBody().getItems());
            logger.info(temp.toString());
            callBack.completed(temp, null);
            cdl.countDown();
        }else {
            logger.error("http reqeust has failed");
        }
    });
    
} 

我已經通過使用.doOnError().onErrorReturn()解決了這個問題

這是我下面的代碼

@Override
public void run() {
    //여기서 API를 호출할거임
    DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(BASE_URL); //UriBuilder를 생성하는 옵션을 설정하는 DefaultUriBuilderFactory 인스턴스 생성
    factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY); //encoding 모드 설정

    
    HttpClient client = HttpClient.create()
            .responseTimeout(Duration.ofSeconds(60)); //http response timeout 설정을 60초로 설정함
    
    WebClient wc = WebClient.builder()
            .uriBuilderFactory(factory) //위에서 만든 uri 인코딩 설정으로 uribuilder 설정을 함
            .baseUrl(BASE_URL) //baseURI 설정하고
            .clientConnector(new ReactorClientHttpConnector(client)) //위에서 만든 타임아웃 설정을 적용시키고
            .build(); //빌드한다.
    
    result = new SweatherRootRes();
    
    //여기서 type mismatch 되는 부분을 찾아야함
    Mono<SweatherRootRes> response = wc.get()
            .uri(uriBuilder -> uriBuilder.path("/getVilageFcst")
                    .queryParam("serviceKey", 123)
                    .queryParam("numOfRows", swr.getNumOfRows())
                    .queryParam("pageNo", swr.getPageNo())
                    .queryParam("dataType", swr.getDataType())
                    .queryParam("base_date", swr.getBase_date())
                    .queryParam("base_time", swr.getBase_time())
                    .queryParam("nx", swr.getNx()) //지역정보
                    .queryParam("ny", swr.getNy()) //지역정보
                    .build()) //위 쿼리들로 uri 빌드를 하고
            .retrieve() //http 요청하고
            .onStatus(HttpStatus::is4xxClientError,
                    error -> Mono.error(new RuntimeException("API not found")))
            .onStatus(HttpStatus::is5xxServerError,
                    error -> Mono.error(new RuntimeException("Server is not responding")))
            .bodyToMono(SweatherRootRes.class)//Mono로 값을 받고
            .doOnError(e -> logger.error("ERROR OCCUR!")) //에러 발생했을때 알려줌
            .onErrorReturn(new SweatherRootRes(true));//에러 발생하면 위 객체를 return 해줌
    
    //비동기 방식으로 약간 콜백 메소드와 같은 역할을 하는것 같다.그래서  이부분은 api 연결이 성공했을때 들어오는 부분인것 같다.
    response.subscribe(res -> {
        if(res.isError()) { //에러라면 진입
            callBack.failed(null, null); //callBack.failed() 호출
        }else {
            result.setResponse(res.getResponse()); //response 값으로 설정
            if(result.getResponse().getBody()!= null) {
                getTemp(result.getResponse().getBody().getItems()); //온도 구해서 세팅
                logger.info(temp.toString());
                callBack.completed(temp, null); //온도 값을 callBack에게 전달
                cdl.countDown(); //Thread 수를 센다.
            }else {
                logger.error("http reqeust has failed");
            }               
        }

    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM