Git :)

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RestTemplate의 Response 결과 값 자동 매핑하기
    Spring Boot/MVC 2023. 11. 25. 20:54

    # 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;
    }

    'Spring Boot > MVC' 카테고리의 다른 글

    Spring Boot Starter별 차이점  (0) 2023.10.22