【问题标题】:Problem with RestTemplate when including URL addresses in REST API request在 REST API 请求中包含 URL 地址时,RestTemplate 出现问题
【发布时间】:2019-10-30 23:15:47
【问题描述】:

我正在尝试从 Botify 的 REST API 获取数据以在项目中使用它,这也是一个 REST API。我正在使用 Spring 的 RestTemplate 类的实例向 Botify 发出实际请求,特别是 .exchange 方法,因为我需要将 Botify 的密钥作为标头参数传递。

当我需要调用端点的方法时,我的问题就出现了,该方法将 URL 作为请求 URI 的一部分(不是参数)。此端点的文档位于https://developers.botify.com/api/reference/#!/Analysis/getUrlDetail

请求的结构基本上是这样的:

/analysiss/{username}/{project_slug}/{analysis_slug}/urls/{url}

该 URI 的最后一部分是 URL 地址,需要以 UTF-8 编码,以便将其与实际请求分开。

问题是(我相信).exchange 方法总是对请求进行编码,所以我尝试这样发送:

/analysiss/myusername/myprojectname/myprojectslug/urls/https%3A%2F%2Fwww.example.com

...最终是这样的:

/analysiss/myusername/myprojectname/myprojectslug/urls/https%253A%252F%252Fwww.example.com'

这显然行不通。这是调用 Botify 的方法的摘录:

public String callBotifyEndpoint(String reportType, String parameters) throws UnsupportedEncodingException {
    String request = this.baseUri + "/analyses/myusername/myprojectname/myprojectslug/urls/https%3A%2F%2Fwww.example.com"

    HttpHeaders headers = new HttpHeaders();
    headers.set("Authorization", "Token " + this.apiKey);
    HttpEntity<String> entity = new HttpEntity<>(headers);

    UriComponentsBuilder botifyQueryBuilder = UriComponentsBuilder.fromUriString(request);      
    String queryStringBuild = botifyQueryBuilder.build(true).toUriString();

    String botifyResult = null;

    try {
        System.out.println("Calling Botify API: " + queryStringBuild);
        ResponseEntity<String> response = botifyTemplate.exchange(queryStringBuild, HttpMethod.GET, entity, String.class);
        if(response.hasBody()) {
            botifyResult = response.getBody();
        }
    } catch(RestClientException ex) {
        ex.printStackTrace();
    }
    try {

    } catch (Exception e) {
        // TODO: handle exception
    }

    return botifyResult;    
}

在这一行:

    botifyQueryBuilder.build(true).toUriString();

“true”参数表示数据是否已经编码。我试过禁用它,但结果是一样的。

我已经删除了实际的请求生成过程(连同我的用户和项目的名称)以简化操作,但这应该会返回来自 Botify 的响应以及该 URL 的现有数据。

相反,它返回 400 bad request 错误(这是有道理的,因为 URL 不正确)。

我觉得这可能是 RestTemplate 的 .exchange 方法中的一个错误,但也许我没有正确使用它。有什么建议吗?

【问题讨论】:

    标签: java spring rest spring-boot resttemplate


    【解决方案1】:

    不要像这里那样过早编码:

    String request = this.baseUri + "/analyses/myusername/myprojectname/myprojectslug/urls/https%3A%2F%2Fwww.example.com";
    

    在 RestTemplate 中使用参数占位符功能而不是文本连接。

    参考: Spring RestTemplate GET with parameters

    【讨论】:

    • 感谢您的回答。我实际上并没有那样构建请求,我简化了功能。但是,我相信我不能使用参数占位符,因为我需要传递给端点的 URL 不是参数:它是请求 URI 的一部分。
    • 澄清一下,这个 GET 请求来自 Postman(使用我的真实用户名、项目名称和分析 slug 以及相应的身份验证标头):api.botify.com/v1/analyses/myusername/myprojectname/…
    • 作为 URI 路径一部分的参数是有效的,即所谓的“路径参数”。 RestTemplate 能够处理它们并应用适当的编码来生成有效的 URL。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    相关资源
    最近更新 更多