在 Spring 中使用 RestTemplate。例外 - 没有足够的变量可用于扩展
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21819210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using RestTemplate in Spring. Exception- Not enough variables available to expand
提问by user3311403
I am trying to access the contents of an API and I need to send a URL using RestTemplate.
我正在尝试访问 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);
But, I am getting the following error.
但是,我收到以下错误。
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)
If I remove the sort criteria, it is working properly. I need to parse the JSON using sort criteria. Any help will be much appreciated.
如果我删除排序标准,它就可以正常工作。我需要使用排序条件解析 JSON。任何帮助都感激不尽。
Thanks
谢谢
回答by Sotirios Delimanolis
The root cause is that RestTemplate
considers curly braces {...}
in the given URL as a placeholder for URI variables and tries to replace them based on their name. For example
根本原因是将给定 URL 中的RestTemplate
花括号{...}
视为 URI 变量的占位符,并尝试根据名称替换它们。例如
{pageSize}
would try to get a URI variable called pageSize
. These URI variables are specified with some of the other overloaded getForObject
methods. You haven't provided any, but your URL expects one, so the method throws an exception.
会尝试获取一个名为 的 URI 变量pageSize
。这些 URI 变量是用其他一些重载getForObject
方法指定的。您尚未提供任何内容,但您的 URL 需要一个,因此该方法会引发异常。
One solution is to make a String
object containing the value
一种解决方案是创建一个String
包含值的对象
String sort = "{\"price\":\"desc\"}";
and provide a real URI variable in your URL
并在您的 URL 中提供一个真实的 URI 变量
String url1 = "http://api.example.com/Search?key=52ddafbe3ee659bad97fcce7c53592916a6bfd73&term=&limit=100&sort={sort}";
You would call your getForObject()
like so
你会打电话给你getForObject()
,像这样
OutputPage page = restTemplate.getForObject(url1, OutputPage.class, sort);
I strongly suggest you do not send any JSON in a request parameter of a GET request but rather send it in the body of a POST request.
我强烈建议您不要在 GET 请求的请求参数中发送任何 JSON,而是在 POST 请求的正文中发送它。
回答by noob
If the solution suggested by sotirios-delimanolisis a little difficult to implement in a scenario, and if the URI string containing curly braces and other characters is guaranteed to be correct, it might be simpler to pass the encoded URI string to a method of RestTemplate
that hits the ReST
server.
如果所建议的解决方案索蒂里奥斯-delimanolis是有点困难的情况下实现的,如果含有大括号和其他字符的URI字符串保证是正确的,它可能是简单的编码的URI字符串传递给的方法RestTemplate
是命中ReST
服务器。
The URI string can be built using UriComponentsBuilder.build(), encoded using UriComponents.encode(), and sent using RestTemplate.exchange()like this:
的URI字符串可以使用内置UriComponentsBuilder.build() ,使用编码UriComponents.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;
}
Building, encoding, and extracting URI have been seperated out for clarity in the above code snippet.
为清楚起见,上述代码片段中已将构建、编码和提取 URI 分开。
回答by Thor
You can URL encode the parameter values:
您可以对参数值进行 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);
回答by Zongguang
You can encode url before using RestTemplate
您可以在使用 RestTemplate 之前对 url 进行编码
URLEncoder.encode(data, StandardCharsets.UTF_8.toString());
回答by Somnath Singh
You can simply append a variable key to the URL and give the value using the restTemplate.getForObject()
method.
您可以简单地将变量键附加到 URL 并使用该restTemplate.getForObject()
方法给出值。
Example:
例子:
String url = "http://example.com/api?key=12345&sort={data}";
String data="{\"price\":\"desc\"}";
OutputPage page = restTemplate.getForObject(url, OutputPage.class, data);