RestTemplate.exchange() не кодирует "+"?

RestTemplate.exchange() закодирует все недопустимые символы в URL, но не + как + является действительным символом URL. Но как пройти + в параметре запроса любого URL?

1 ответ

Если URI, который вы передаете в RestTemplate, имеет кодированное значение 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 как кодирование будет выполнено дважды.
Другие вопросы по тегам