如何在 Spring 启动时处理 UnsupportedMediaTypeException?
How to handle UnsupportedMediaTypeException in Spring Boot?
您好,我正在尝试在 spring 启动时使用 Webclient 调用 API。
但我遇到了一些问题。
虽然我请求的响应是json响应,但当服务器发生错误时,服务器给我一个xml响应。
所以当服务器发生错误时我收到 UnsupportedMediaTypeException 错误。
因此我想制作一个业务逻辑,当发生 UnsupportedMediaTypeException 错误时可以给我发送电子邮件。
如何处理 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");
}
}
});
}
您好,我正在尝试在 spring 启动时使用 Webclient 调用 API。
但我遇到了一些问题。
虽然我请求的响应是json响应,但当服务器发生错误时,服务器给我一个xml响应。
所以当服务器发生错误时我收到 UnsupportedMediaTypeException 错误。
因此我想制作一个业务逻辑,当发生 UnsupportedMediaTypeException 错误时可以给我发送电子邮件。
如何处理 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");
}
}
});
}