在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:33:45  来源:igfitidea点击:

Using RestTemplate in Spring. Exception- Not enough variables available to expand

springresttemplate

提问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 RestTemplateconsiders 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 getForObjectmethods. 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 Stringobject 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 RestTemplatethat hits the ReSTserver.

如果所建议的解决方案索蒂里奥斯-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);