Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
663 views
in Technique[技术] by (71.8m points)

java - RestTemplate.exchange() does not encode '+'?

The RestTemplate.exchange() will encode all the invalid characters in URL but not + as + is a valid URL character. But how to pass a + in any URL's query parameter?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If the URI you pass to the RestTemplate has encoded set as true then it will not perform the encoding on the URI you pass else it will do.

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);
  }

}

So if you need to pass a query param with + in it then the RestTemplate will not encode the + but every other invalid URL character as + is a valid URL character. Hence you have to first encode the param (URLEncoder.encode("abc+123=", "UTF-8")) and then pass the encoded param to RestTemplate stating that the URI is already encoded using builder.build(true).toUri();, where true tells the RestTemplate that the URI is alrady encoded so not to encode again and hence the + will be passed as %2B.

  1. With builder.build(true).toUri(); OUTPUT : http://example.com/endpoint?param1=abc%2B123%3D as the encoding will be perfromed once.
  2. With builder.build().toUri(); OUTPUT : http://example.com/endpoint?param1=abc%252B123%253D as the encoding will be perfromed twice.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...