RestTemplate 쓸 때 에러핸들러, Interceptors 등록, 사용법

우서봐·2023년 3월 21일
0

목적

RestTemplate 쓸 때 오류 발생시 한 곳에서(공통) 로그 출력을 하고 싶다

목차

  1. RestTemplate 빈등록
    1-1. set 에러핸들러
    1-2. set Interceptors 방법
  2. set 에러핸들러용 RestTemplateErrorHandler 클래스 생성
  3. set Interceptors용 RestTemplateLoggingInterceptor 클래스 생성
  1. RestTemplate 빈등록 주요부분
	RestTemplate restTemplate = new RestTemplate();
	restTemplate.setErrorHandler(new RestTemplateErrorHandler());
	restTemplate.setRequestFactory(bufferFactory);
	restTemplate.setInterceptors(Lists.newArrayList(new RestTemplateLoggingInterceptor()));
	return restTemplate; 

RestTemplate 빈등록 전체코드

package com.config;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import com.google.common.collect.Lists;
import com.common.interceptor.RestTemplateLoggingInterceptor;
import com.restapi.error.RestTemplateErrorHandler;

@Configuration
public class ApplicationConfig {
	
	@Bean
	public RestTemplate restTemplateCustomErrorHandler() { 
		HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); 
		factory.setReadTimeout(5000); 		// read timeout 
		factory.setConnectTimeout(3000); 	// connection timeout 
		
		//Apache HttpComponents HttpClient 
		HttpClient httpClient = HttpClientBuilder.create() 
				.setMaxConnTotal(50)	//최대 커넥션 수 
				.setMaxConnPerRoute(20).build(); //각 호스트(IP와 Port의 조합)당 커넥션 풀에 생성가능한 커넥션 수 
		
		factory.setHttpClient(httpClient); 
		BufferingClientHttpRequestFactory bufferFactory = new BufferingClientHttpRequestFactory(factory);
		
		RestTemplate restTemplate = new RestTemplate();
		restTemplate.setErrorHandler(new TmsRestTemplateErrorHandler());
		restTemplate.setRequestFactory(bufferFactory);
		restTemplate.setInterceptors(Lists.newArrayList(new RestTemplateLoggingInterceptor()));
		return restTemplate; 
	}

}
  1. set 에러핸들러용 RestTemplateErrorHandler 클래스 생성
package com.restapi.error;

import java.io.IOException;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;

public class RestTemplateErrorHandler implements ResponseErrorHandler {

	private Logger logger = Logger.getLogger(this.getClass());
	
	@Override
    public boolean hasError(ClientHttpResponse httpResponse) 
      throws IOException {
        return (
          httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR 
          || httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR);
    }

    @Override
    public void handleError(ClientHttpResponse httpResponse) 
      throws IOException {
    	
    	if (httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
    		 // handle SERVER_ERROR
    		ToStringBuilder builder = new ToStringBuilder("\n", ToStringStyle.MULTI_LINE_STYLE) 
				.append("=========================================================") 
				.append("| TmsRestTemplateErrorHandler") 
				.append("|--------------------------------------------------------") 
				.append("| StatusCode :: " + httpResponse.getStatusCode())
				.append("=========================================================");
    		logger.error(builder.toString());
        } else if (httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
            // handle CLIENT_ERROR
    		ToStringBuilder builder = new ToStringBuilder("\n", ToStringStyle.MULTI_LINE_STYLE) 
				.append("=========================================================") 
				.append("| TmsRestTemplateErrorHandler") 
				.append("|--------------------------------------------------------") 
				.append("| StatusCode :: " + httpResponse.getStatusCode())
				.append("=========================================================");
    		logger.error(builder.toString());
            if (httpResponse.getStatusCode() == HttpStatus.NOT_FOUND) {
//                throw new NotFoundException();
            }
        }
    }

}
  1. set Interceptors용 RestTemplateLoggingInterceptor 클래스 생성
public class RestTemplateLoggingInterceptor implements ClientHttpRequestInterceptor {

	private Logger logger = Logger.getLogger(this.getClass());

//	private final int MAX_BODY_CONTENTS_LENGTH = 2000;

	@Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body,
        ClientHttpRequestExecution execution) throws IOException {
		
		ClientHttpResponse response = execution.execute(request, body); 
		HttpStatus httpStatus = response.getStatusCode(); 
		
		if (httpStatus.is4xxClientError() || httpStatus.is5xxServerError()) { 
			writeErrorLog(request, body, response); 
		} 
		return response;
    }
	
	private void writeErrorLog(HttpRequest request, byte[] body, ClientHttpResponse response) throws IOException {
		ToStringBuilder builder = new ToStringBuilder("\n", ToStringStyle.MULTI_LINE_STYLE) 
			.append("=========================================================") 
			.append("| RestServicErrorLog") 
			.append("|--------------------------------------------------------") 
			.append("| URI :: " + request.getURI()) .append("| Method :: " + request.getMethod())
			//.append("| Headers :: " + response.getHeaders()) 
			.append("| Request Body :: " + new String(body, StandardCharsets.UTF_8))
			.append("|--------------------------------------------------------") 
			.append("| Status Code :: " + response.getStatusCode()) 
			.append("| Status Text :: " + response.getStatusText()) 
			//.append("| Headers :: " + response.getHeaders()) 
			.append("| Response Body : " + StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8));
		builder.append("========================================================="); 
		logger.error(builder.toString()); 
	} 
}

0개의 댓글