如何使用 Spring RestTemplate 将 JSON 作为参数发送到 url 中?

How to send JSON as a parameter in url using Spring RestTemplate?

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

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

注意:提到的相关问题并没有指导如何克服这个问题,我没有足够的声誉来评论它来询问答案的作者。

您可以使用URLEncoder class 将URL 编码为exchange 方法,例如:

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

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

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

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

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 query/url 参数的 url 作为字符串传递,而是将其作为 URI 传递。然后像以前一样调用 exchange 方法,但使用 URI 而不是 String:

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