RestTemplate

천진우·2021년 12월 15일
0

RestTemplate이란?

  • Spring에서 제공하는 http통신에 사용하는 템플릿
  • Spring3.0부터 지원
  • RestAPI 호출 이후 응답을 받을 때까지 기다리는 동기 방식

RestTemplate 동작원리

  1. 어플리케이션이 RestTemplate를 생성하고, URI, HTTP메소드 등의 헤더를 담아 요청한다.
  2. RestTemplate 는 HttpMessageConverter 를 사용하여 requestEntity 를 요청메세지로 변환한다.
  3. RestTemplate 는 ClientHttpRequestFactory 로 부터 ClientHttpRequest 를 가져와서 요청을 보낸다.
  4. ClientHttpRequest 는 요청메세지를 만들어 HTTP 프로토콜을 통해 서버와 통신한다.
  5. RestTemplate 는 ResponseErrorHandler 로 오류를 확인하고 있다면 처리로직을 태운다.
  6. ResponseErrorHandler 는 오류가 있다면 ClientHttpResponse 에서 응답데이터를 가져와서 처리한다.
  7. RestTemplate 는 HttpMessageConverter 를 이용해서 응답메세지를 java object(Class responseType) 로 변환한다.
  8. 어플리케이션에 반환된다.

RestTemplate Method

1. getForObject <-> getForEntity

getForObject

RestTemplate restTemplate = new RestTemplate();
Object response = restTemplate.getForObject(uri, Object.class);

getForEntity

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Object> response = restTemplate.getForObject(uri, Object.class);

System.out.println(response.getStatusCode()); // 200 ok
System.out.println(response.getHeaders());
System.out.println(response.getBody());

2. postForEntity

postForEntity

UserRequest req = new UserRequest();
req.setName("steve");
req.setAge(10);

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<UserResponse> response = restTemplate.postForObject(uri, req, UserResponse.class);

System.out.println(response.getStatusCode()); // 200 ok
System.out.println(response.getHeaders());
System.out.println(response.getBody());

3. 헤더 지정(exchange)

UserRequest req = new UserRequest();
req.setName("steve");
req.setAge(10);

RequestEntity<UserRequest> requestEntity = RequestEntity
	.post(uri)
	.contentType(MediaType.APPLICATON_JSON)
	.header(“x-authorization”, “abcd”)
	.header(“custom-header”, “ffff”)
	.body(req);

RestTemplate restTemplate = new RestTemplate();
RestponseEntity<userResponse> response = restTemplate.exchange(requestEntity, UserResponse.class);

4. generic

//response class
Public class Req<T> {
	private String exampleString;
	private T exampleObject;
}

//restTemplate
restTemplate.exchange(requestEntity, Req<someObject>.class);

-> 오류 발생 -> generic class에는 .class를 붙일 수 없다

restTemplate.exchange(requestEntity, new ParameterizedTypeReference<Req<someObject>>(){});

ResponseEntity<Req<someObject>> response = restTemplate.exchange(requestEntity, new ParameterizedTypeReference<>(){});
//responseEntity<>안에 타입을 지정해두어 ParameterizedTypeReference의 <>는 생략 가능

URI

1. new URI

URI uri = new URI(str);

2. URI.create(str)

URI uri = URI.create(str);

// create(str) code
public static URI create(String str) {
	try {
    		return new URI(str);
        } catch (URISyntaxException x) {
        	throw new IllegalArgumentException(x.getMessage(), x);
        }
 }

생성되는 결과는 같지만 exception 처리를 해준다

3. UriComponentsBuilder

URI uri = UriComponentsBuilder
	.fromUriString("http://localhost:8080")
    	.path("/api/server/hello")
        .encode() // 인코딩 (default : UTF-8)
        .build() // 인스턴스 빌드
        .toUri();

// http://localhost:8080/api/server/hello

queryParam

URI uri = UriComponentsBuilder
	.fromUriString("http://localhost:8080")
    	.path("/api/server/hello")
    	.queryParam("id", "testId")
        .queryParam("type", "0000")
        .encode()
        .build()
        .toUri();

// http://localhost:8080/api/server/hello?id=testId&type=0000

http://localhost:8080/api/server/user/{userId}/name/{userName}

URI uri = UriComponentsBuilder
	.fromUriString("http://localhost:8080")
    	.path("/api/server/user/{userId}/name/{userName}")
        .encode()
        .build()
        .expand(100, "steve")
        .toUri();

// http://localhost:8080/api/server/user/100/name/steve

	// 주의
	.expand(100)
    	.expand("steve")
        // -> 오류 발생 : 첫 번째 expand()만 인식된다

RestTemplate과 함께 사용시 주의사항

// RestTemplate + URI/String
String uri = UriComponentsBuilder...

String타입의 경우 RestTemplate에서 내부적으로 인코딩을 수행
-> 인코딩 중복 수행될 수 있다
-> RestTemplate과 함께 사용한다면 URI로 생성하거나 인코딩 되지 않은 String을 생성하여 사용

기타

restTemplate.getForObject(uri, String.class)
-> restTemplate을 통해 response를 string으로 변환시 한글 깨짐 현상 발생

HttpMessageConverter : HTTP request / response를 변환
StringHttpMessageConverter : Http response를 String으로 변환
-> default Charset : ISO-8859-1

template.getMessageConverters()
                .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));

-> 한글 깨짐 현상 해결

0개의 댓글