【问题标题】:How to send JSON as a parameter in url using Spring RestTemplate?如何使用 Spring RestTemplate 在 url 中将 JSON 作为参数发送?
【发布时间】:2017-09-01 08:10:33
【问题描述】:

我正在尝试实现与此相同的事情:How to use query parameter represented as JSON with Spring RestTemplate?,在restTemplate.exchange() 中将 JSON 字符串作为 URL 参数发送。

接受的答案提到将 JSON 对象作为请求参数发送通常不是一个好主意,因为您可能会遇到 JSON 中的大括号问题。这正是我尝试对 API 进行 GET 调用时发生的情况。由于这是来自另一个系统的 API,我不能要求他们更改格式,并且必须调用 GET 端点,将 JSON 作为参数传递。如何在restTemplate.exchange() 通话中实现这一点?

注意:提到的相关问题并未指导如何克服此问题,我没有足够的声誉对此发表评论以询问答案的作者。

【问题讨论】:

  • 对链接问题的回答有什么问题?你的代码是什么?你有什么确切和完整的错误?
  • 我得到的错误是:java.lang.IllegalArgumentException: Not enough variable values available to expand '"size"'。 json 看起来像这样:{"size":10000,"query":{"filtered":{"filter":{"term":{"run_id":"a5fc0cdb-0bce-4071-a850-77d181c0811d"}}}}}
  • 链接的问题只显示了如何从对象中获取 JSON,而不是如何在 exchange() 中使用它以避免我上面提到的错误。
  • 如果您需要有关代码的帮助,请发布您的代码。是的,它确实展示了如何使用参数值构建 URL。
  • @JBNizet:我明白了。我通过发送 URI 而不是字符串来实现它。谢谢!

标签: java json spring resttemplate


【解决方案1】:

回答我自己的问题。虽然在查询/url 参数中传递这样的 JSON 是一个坏主意,但这里有一个建议的解决方法:https://jira.spring.io/browse/SPR-9220?focusedCommentId=76760&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-76760
如果此链接失效,请在此处复制代码:

String url = "http://localhost:8983/solr/select?wt=json&indent=true&fl=*&q=*:*&fq={!geofilt}&sfield=venue_location&pt=28.0674,-80.5595&d=25";
URI uri = UriComponentsBuilder.fromUriString(url).build().encode().toUri();

System.out.println(uri);
// http://localhost:8983/solr/select?wt=json&indent=true&fl=*&q=*:*&fq=%7B!geofilt%7D&sfield=venue_location&pt=28.0674,-80.5595&d=25

基本上,不是将具有 JSON 查询/url 参数的 url 作为字符串传递,而是将其作为 URI 传递。然后像以前一样调用exchange方法,但是使用URI而不是String:

restTemplate.exchange(uri, HttpMethod.GET, requestEntity, String.class)

【讨论】:

  • 感谢您的解决方案,传递 URI 就像一个魅力!就我而言,我需要传递一些参数:UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url); URI uri = builder.build().expand(params).encode().toUri(); restTemplate.getForObject(uri, String.class);
【解决方案2】:

如果这是第 3 方 API,并且您无法控制或更改后端的 JSON 处理 - 没有解决方案。即使您将使用 URLEncoder 进行编码 - 也不能保证 API 后端会正确处理此类请求。

【讨论】:

    【解决方案3】:

    您可以使用URLEncoder 类对exchange 方法中的URL 进行编码,例如:

    String url = "http://www.yoursite.com/api?param={\"some_key\":\"some_value\"}";
    System.out.println(URLEncoder.encode(url, StandardCharsets.UTF_8.name()));
    

    这将对字符(如大括号和双引号)进行编码,然后服务器会将其解码回json

    【讨论】:

    • 我试过这个。但是exchange 方法最终会在此编码之上添加另一个编码,基本上将所有% 替换为%25。因此,解码后服务器得到的是另一个编码字符串。
    • 如果你发送的请求没有编码怎么办?你得到 4xx 还是 5xx 作为回报?
    • 我得到的错误是:java.lang.IllegalArgumentException: Not enough variable values available to expand '"size"'。 json 看起来像这样:{"size":10000,"query":{"filtered":{"filter":{"term":{"run_id":"a5fc0cdb-0bce-4071-a850-77d181c0811d"}}}}}
    • 所以,我假设它是从服务器返回的(可能是 500 错误)?如果是,您能否发布exchange 方法的代码?
    • @Darshan Mehta:不,在构建 URL 时抛出异常,甚至在进行网络调用之前。我会尽快添加我的代码。
    猜你喜欢
    • 1970-01-01
    • 2012-12-18
    • 2020-06-10
    • 2019-08-03
    • 1970-01-01
    • 2012-11-01
    • 2016-11-22
    • 2016-06-30
    • 1970-01-01
    相关资源
    最近更新 更多