RestTemplate.exchange()方法不会对'+'进行编码吗?

5

RestTemplate.exchange()方法会对URL中所有无效字符进行编码,但不会将+编码,因为它是一个合法的URL字符。但是如果想在任何URL的查询参数中传递+,该怎么办呢?

1个回答

15

如果您向RestTemplate传递的URI中将encoded设置为true,则它不会对您传递的URI进行编码,否则它将执行编码。

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.Collections;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

class Scratch {

  public static void main(String[] args) {

    RestTemplate rest = new RestTemplate(
        new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));

    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/json");
    headers.add("Accept", "application/json");
    HttpEntity<String> requestEntity = new HttpEntity<>(headers);

    UriComponentsBuilder builder = null;
    try {
      builder = UriComponentsBuilder.fromUriString("http://example.com/endpoint")
          .queryParam("param1", URLEncoder.encode("abc+123=", "UTF-8"));
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }

    URI uri = builder.build(true).toUri();
    ResponseEntity responseEntity = rest.exchange(uri, HttpMethod.GET, requestEntity, String.class);
  }

}
如果您需要传递带有+的查询参数,则RestTemplate不会对+进行编码,但将所有其他无效的URL字符都编码为+,因为+是URL中有效的字符。因此,您必须先对参数进行编码(URLEncoder.encode("abc+123=", "UTF-8")),然后将编码后的参数传递给RestTemplate,指定URI已经使用builder.build(true).toUri();进行了编码,其中true告诉RestTemplate URI已经被编码过了,所以不要再次编码,因此+将被传递为%2B
  1. 使用 builder.build(true).toUri(); 输出: http://example.com/endpoint?param1=abc%2B123%3D 因为编码只会执行一次。
  2. 使用 builder.build().toUri(); 输出: http://example.com/endpoint?param1=abc%252B123%253D 因为编码将执行两次。

1
我曾经遇到同样的问题,你的答案帮助我解决了我的问题。 - Debesh Nayak
很高兴它能帮到你。 - Raj Rajeshwar Singh Rathore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接