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
が、指定されたURL内の中括弧_{...}
_をURI変数のプレースホルダーと見なし、名前に基づいてそれらを置換しようとすることです。例えば
_{pageSize}
_
pageSize
というURI変数を取得しようとします。これらのURI変数は、他のオーバーロードされたいくつかの getForObject
メソッドで指定されます。あなたは何も提供していませんが、URLはそれを期待しているので、メソッドは例外をスローします。
1つの解決策は、値を含む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リクエストの本文で送信することを強くお勧めします。
パラメーター値を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);
sotirios-delimanolis によって提案されたソリューションがシナリオで実装するのが少し難しく、中括弧やその他の文字を含むURI文字列が正しいことが保証されている場合、エンコードされたRestTemplate
サーバーにヒットするReST
のメソッドへのURI文字列。
URI文字列は、 riComponentsBuilder.build() を使用して構築し、 riComponents.encode() を使用してエンコードし、 RestTemplate.exchange() を使用して送信できます。このような:
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の構築、エンコード、および抽出は、上記のコードスニペットでわかりやすくするために分離されています。
RestTemplateを使用する前にURLをエンコードできます
URLEncoder.encode(data, StandardCharsets.UTF_8.toString());
urlに変数を追加して、変数の値を restTemplate.postForObject 方法。
String url1 = "http://api.example.com/Search?
key=52ddafbe3ee659bad97fcce7c53592916a6bfd73&term=&limit=100&sort={data}";
String data="{\"price\":\"desc\"}";
OutputPage page = restTemplate.getForObject(url1, OutputPage.class, data);