繁体   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