programing

봄에 휴식 템플릿을 사용합니다.예외 - 확장할 수 있는 변수가 충분하지 않습니다.

oldcodes 2023. 9. 6. 22:18
반응형

봄에 휴식 템플릿을 사용합니다.예외 - 확장할 수 있는 변수가 충분하지 않습니다.

API의 내용을 접속하려고 하는데 RestTemplate를 이용해서 URL을 보내야 합니다.

String url1 = "http://api.example.com/Search?key=52ddafbe3ee659bad97fcce7c53592916a6bfd73&term=&limit=100&sort={\"price\":\"desc\"}";

OutputPage page = restTemplate.getForObject(url1, OutputPage .class);

하지만 저는 다음과 같은 오류가 발생하고 있습니다.

Exception in thread "main" java.lang.IllegalArgumentException: Not enough variable values available to expand '"price"'
at org.springframework.web.util.UriComponents$VarArgsTemplateVariables.getValue(UriComponents.java:284)
at org.springframework.web.util.UriComponents.expandUriComponent(UriComponents.java:220)
at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:317)
at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:46)
at org.springframework.web.util.UriComponents.expand(UriComponents.java:162)
at org.springframework.web.util.UriTemplate.expand(UriTemplate.java:119)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:501)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:239)
at hello.Application.main(Application.java:26)

정렬 기준을 제거하면 제대로 작동합니다.정렬 기준을 이용해서 JSON을 파싱해야 합니다.어떤 도움이라도 주시면 감사하겠습니다.

감사해요.

근본적인 원인은RestTemplate곱슬곱슬한 교정기를 고려합니다.{...}URI 변수의 자리 표시자로 지정된 URL에서 해당 변수의 이름을 기준으로 대체하려고 합니다.예를들면

{pageSize}

다음과 같은 URI 변수를 가져오려고 시도할 것입니다.pageSize. 이러한 URI 변수는 일부 다른 오버로드된 메서드와 함께 지정됩니다.제공하지 않았지만 URL에서 제공할 것으로 예상하므로 메서드에서 예외가 발생합니다.

한가지 해결책은.String값이 들어 있는 개체

String sort = "{\"price\":\"desc\"}";

URL에 실제 URI 변수를 제공합니다.

String url1 = "http://api.example.com/Search?key=52ddafbe3ee659bad97fcce7c53592916a6bfd73&term=&limit=100&sort={sort}";

당신은 당신의 전화를getForObject()이와 같이

OutputPage page = restTemplate.getForObject(url1, OutputPage.class, sort);

GET 요청의 요청 파라미터에 JSON을 보내지 말고 POST 요청의 본문으로 보내시기를 강력히 제안합니다.

sotirios-delimanolis에 의해 제안된 해결책이 시나리오에서 구현하기 조금 어렵고 curly brases와 다른 문자를 포함하는 URI 문자열이 정확하다고 보장된다면 인코딩된 URI 문자열을 다음의 방법으로 전달하는 것이 더 간단할 수 있습니다.RestTemplate을 강타하는ReST서버.

URI 문자열은 URI ComponentsBuilder를 사용하여 작성할 수 있습니다.build(), uriComponents.encode()를 사용하여 인코딩되고 RestTemplate를 사용하여 전송됩니다.다음과 같이 교환합니다.

public ResponseEntity<Object> requestRestServer()
{
    HttpEntity<?> entity = new HttpEntity<>(requestHeaders);
    UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(rawValidUrl)
            .queryParams(
                    (LinkedMultiValueMap<String, String>) allRequestParams);
    UriComponents uriComponents = builder.build().encode();
    ResponseEntity<Object> responseEntity = restTemplate.exchange(uriComponents.toUri(), HttpMethod.GET,
            entity, String.class);
    return responseEntity;
}

위 코드 조각에서 명확성을 위해 URI 구축, 인코딩 및 추출이 분리되었습니다.

URL에서 매개 변수 값을 인코딩할 수 있습니다.

String url1 = "http://api.example.com/Search?key=52ddafbe3ee659bad97fcce7c53592916a6bfd73&term=&limit=100&sort=";

org.apache.commons.codec.net.URLCodec codec = new org.apache.commons.codec.net.URLCodec();
url1 = url1 + codec.encode("{\"price\":\"desc\"}");
OutputPage page = restTemplate.getForObject(url1, OutputPage.class);

restTemplate에서 특정 UriTemplateHandler를 설정할 수 있습니다.이 처리기는 uriVariables를 무시합니다.

UriTemplateHandler skipVariablePlaceHolderUriTemplateHandler = new UriTemplateHandler() {
    @Override
    public URI expand(String uriTemplate, Object... uriVariables) {
        return retrieveURI(uriTemplate);
    }

    @Override
    public URI expand(String uriTemplate, Map<String, ?> uriVariables) {
        return retrieveURI(uriTemplate);
    }

    private URI retrieveURI(String uriTemplate) {
        return UriComponentsBuilder.fromUriString(uriTemplate).build().toUri();
    }
};

restTemplate.setUriTemplateHandler(skipVariablePlaceHolderUriTemplateHandler);

RestTemplate를 사용하기 전에 url을 인코딩할 수 있습니다.

URLEncoder.encode(data, StandardCharsets.UTF_8.toString());

URL에 변수 키를 추가하고 메소드를 사용하여 값을 지정하면 됩니다.

예:

String url = "http://example.com/api?key=12345&sort={data}";
String data="{\"price\":\"desc\"}";

OutputPage page = restTemplate.getForObject(url, OutputPage.class, data);

언급URL : https://stackoverflow.com/questions/21819210/using-resttemplate-in-spring-exception-not-enough-variables-available-to-expan

반응형