# RestTemplate의 exchange 메소드
public <T> ResponseEntity<T> exchange(String url, HttpMethod method,
@Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
# 4번째 인자값인 responseType을 통해 결과값을 반환받는 방법
- 아래와 같은 구조를 가진 객체를 생성하면 된다.
- 내부적으로 MessageConverter를 동작시켜 같은 변수명을 가진 필드들을 매핑시켜준다.
public class ResponseVO {
private Integer status ;
private String code ;
private String message ;
private Object data ;
}
# 실제 사용한 소스코드
ResponseEntity<ResponseVO> responseEntity = restTemplate.exchange(uri, HttpMethod.GET, entity, ResponseVO.class) ;
ResponseVO responseVO = responseEntity.getBody();
log.info("responseVO ---------> {}", responseVO) ;
# uriVariables 쓰면 안되는 이유 (쓰더라도 알고쓰자)
- 결론부터 얘기하면 해당 내용은 자동으로 uri에 결과값을 매핑해주는 편리한 도구이다.
- 하지만 내부 macher 로직을 보면 아래와 같이 synchronized가 걸려있다.
- 편리하고 저것으로 인한 큰 이슈는 없을 거 같지만, 정말 만약 대용량 트래픽이 발생하는 서비스라면 굳이 lock을 걸면서까지 써야할 필요는 없다고 판단된다.
@Nullable
static String expandUriComponent(@Nullable String source, UriTemplateVariables uriVariables,
@Nullable UnaryOperator<String> encoder) {
if (source == null) {
return null;
}
if (source.indexOf('{') == -1) {
return source;
}
if (source.indexOf(':') != -1) {
source = sanitizeSource(source);
}
Matcher matcher = NAMES_PATTERN.matcher(source);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String match = matcher.group(1);
String varName = getVariableName(match);
Object varValue = uriVariables.getValue(varName);
if (UriTemplateVariables.SKIP_VALUE.equals(varValue)) {
continue;
}
String formatted = getVariableValueAsString(varValue);
formatted = encoder != null ? encoder.apply(formatted) : Matcher.quoteReplacement(formatted);
matcher.appendReplacement(sb, formatted);
}
matcher.appendTail(sb);
return sb.toString();
}
- 가운데 라인의 NAMES_PATTERN.matcher(source)의 내부 소스를 보면,,, synchronized가 걸려있는 것을 확인할 수 있다.
public Matcher matcher(CharSequence input) {
if (!compiled) {
synchronized(this) {
if (!compiled)
compile();
}
}
Matcher m = new Matcher(this, input);
return m;
}