이슈

RestTemplate 에러

샐리_ 2023. 9. 12. 09:28

에러가 발생하였다..

public Response send(Request request) thorws JsonProcessingException {
    try {
        WebRequest webRequest = new WebRequest();
        headers.setContentType(Media.APPLICATION_JSON);
        String url = apiUrl + "/test";
		
        ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethos.POST, new HttpEntity<>(webRequest, headers), new ParameterizedTypeReference<>() {});   // 이 부분에서 오류 발생
        ...
    }
}

ConcurrentModificationException이 발생하였다.

아래는 해당 에러 로그의 일부이다.

2023-06-16 13:49:05.303 ERROR 2468 --- [  XNIO-1 task-2] c.k.a.k.services.ServiceImpl   : Exception

java.util.ConcurrentModificationException: null
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1390) ~[na:1.8.0_341]
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[na:1.8.0_341]
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[na:1.8.0_341]
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_341]
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_341]
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_341]
	at org.springframework.web.client.RestTemplate$AcceptHeaderRequestCallback.doWithRequest(RestTemplate.java:855) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:915) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:737) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:674) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:612) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]

해당 Exception을 찾아보면 대부분 리스트나 맵 등 Iterable 객체를 순회하면서 요소를 삭제하거나 변경할 때 발생한다고 나온다.

restTemplate을 사용하는 부분인데...

검색한 내용은 발생한 에러와 맞지 않으니 수정된 코드를 다시 살펴보자.

수정된 코드를 보니 에러 발생 원인으로 추정되는 부분을 찾을 수 있었다.

에러가 발생한 REST 호출 이전 REST 호출하는 부분에서 데이터 규격이 application/json이 아닌 application/x-www-form-urlencoded 형식을 사용하여 header의 contentType을 변경하고, 그에 필요한 객체를 messgaeConverter에 추가하였다. 그러나 이 객체들을 빈이 관리하도록 하거나, messageConverter에 추가한 객체들을 사용 후 해지하였어야 하는데 그러한 과정이 없었다.

// 오류 발생 restTemplate 이전 설정 부분
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());

 

이 문제는 application/x-www-form-urlencoded 형식을 사용하는 restTemplate을 새로 만들어 스프링 Bean에 등록하였다.

 

결론

필요한 것들을 추가로 작업하였으면 해지하는 것을 잊지 말자.

그리고 스프링 부트는 직접 컨트롤하려고 하지 말고 빈에게 넘기자.

반응형