【问题标题】:RestTemplate to NOT escape urlRestTemplate 不转义 url
【发布时间】:2015-03-26 19:07:51
【问题描述】:

我正在像这样成功使用 Spring RestTemplate:

String url = "http://example.com/path/to/my/thing/{parameter}";
ResponseEntity<MyClass> response = restTemplate.postForEntity(url, payload, MyClass.class, parameter);

这很好。

但是,有时parameter%2F。我知道这并不理想,但它就是这样。正确的 URL 应该是:http://example.com/path/to/my/thing/%2F 但是当我将parameter 设置为"%2F" 时,它会被双重转义为http://example.com/path/to/my/thing/%252F。如何防止这种情况发生?

【问题讨论】:

    标签: java spring resttemplate


    【解决方案1】:

    不要使用String URL,而是使用UriComponentsBuilder 构建URI

    String url = "http://example.com/path/to/my/thing/";
    String parameter = "%2F";
    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url).path(parameter);
    UriComponents components = builder.build(true);
    URI uri = components.toUri();
    System.out.println(uri); // prints "http://example.com/path/to/my/thing/%2F"
    

    UriComponentsBuilder#build(boolean)表示

    此构建器中设置的所有组件是否编码 (true) 或未编码 (false)

    这或多或少等同于替换{parameter} 并自己创建一个URI 对象。

    String url = "http://example.com/path/to/my/thing/{parameter}";
    url = url.replace("{parameter}", "%2F");
    URI uri = new URI(url);
    System.out.println(uri);
    

    然后您可以使用这个URI 对象作为postForObject 方法的第一个参数。

    【讨论】:

    • 谢谢。我最终以不同的方式解决了这个问题。在现实生活中,我的 URL 看起来更像http://example.com/path/{param}/to/place,所以我做了UriComponentsBuilder.fromHttpUrl(url.replace("{param}", parameter))
    • 我发现使用 UriComponentsBuilder.fromUriString() 而不是 fromHttpUrl() 更好,因为它允许使用 /path/without/host 形式的 URI,这在使用 Spring MockMvc 进行测试时很有用。
    • 为什么这不是错误?它至少应该记录在 Javadoc 中。
    • @GeorgeSofianos 它记录在RestTemplate javadoc、hereNote 中。假定模板参数需要编码。
    【解决方案2】:

    您可以告诉其余模板您已经对 uri 进行了编码。这可以使用 UriComponentsBuilder.build(true) 来完成。这样,rest 模板将不会重新尝试转义 uri。大多数其余模板 api 将接受 URI 作为第一个参数。

    String url = "http://example.com/path/to/my/thing/{parameter}";
    url = url.replace("{parameter}", "%2F");
    UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url);
    // Indicate that the components are already escaped
    URI uri = builder.build(true).toUri();
    ResponseEntity<MyClass> response = restTemplate.postForEntity(uri, payload, MyClass.class, parameter);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-19
      • 2014-01-20
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 2019-11-12
      相关资源
      最近更新 更多