Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Follow 302 redirect using Spring restTemplate?

  RestTemplate restTemplate = new RestTemplate();

  final MappingJackson2XmlHttpMessageConverter converter = new MappingJackson2XmlHttpMessageConverter();
  final List<MediaType> supportedMediaTypes = new LinkedList<MediaType>(converter.getSupportedMediaTypes());
  supportedMediaTypes.add(MediaType.ALL);
  converter.setSupportedMediaTypes(supportedMediaTypes);
  restTemplate.getMessageConverters().add(converter);  


  ResponseEntity<MyDTO[]> response = restTemplate.getForEntity(urlBase, MyDTO[].class);

  HttpHeaders headers = response.getHeaders();
  URI location = headers.getLocation(); // Has my redirect URI

  response.getBody(); //Always null

I was under the impression that a 302 would automatically be followed. Am I incorrect in this assumption? I now need to pick off this location and re-request?

like image 274
techie.brandon Avatar asked Apr 02 '15 17:04

techie.brandon


People also ask

Does RestTemplate follow redirect?

RestTemplate provides support to all HTTP Methods. Most popular are GET and POST. So when we are calling any webservice endpoint using RestTemplate GET or POST there are chances that in response you get Redirect response (302 HTTP Status code). Which indicates that this response is going yo redirect to some other URL.

Does RestTemplate use ObjectMapper?

So, by simply using the RestTemplateBuilder our RestTemplate will automatically use a MappingJackson2HttpMessageConverter configured with an ObjectMapper that uses the required ParameterNamesModule.

How do I redirect a page in Spring boot?

We can use a name such as a redirect: http://localhost:8080/spring-redirect-and-forward/redirectedUrl if we need to redirect to an absolute URL.

What is RestTemplate postForObject?

RestTemplate's postForObject method creates a new resource by posting an object to the given URI template. It returns the result as automatically converted to the type specified in the responseType parameter.


3 Answers

Using the default ClientHttpRequestFactory implementation - which is the SimpleClientHttpRequestFactory - the default behaviour is to follow the URL of the location header (for responses with status codes 3xx) - but only if the initial request was a GETrequest.

Details can be found in this class - searching for the following method:

protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {

    ...

    if ("GET".equals(httpMethod)) {
        connection.setInstanceFollowRedirects(true);
    }

Here the relevant doc comment of HttpURLConnection.setInstanceFollowRedirects method:

Sets whether HTTP redirects (requests with response code 3xx) should be automatically followed by this {@code HttpURLConnection} instance.

The default value comes from followRedirects, which defaults to true.

like image 180
fateddy Avatar answered Oct 29 '22 16:10

fateddy


Are you trying to redirect from one protocol to another, e.g. from http to https or vise versa? If so the automatic redirect won't work. See this comment: URLConnection Doesn't Follow Redirect

After discussion among Java Networking engineers, it is felt that we shouldn't automatically follow redirect from one protocol to another, for instance, from http to https and vise versa, doing so may have serious security consequences

from https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4620571

Otherwise if you debug the RestTemplate code you will see that by default HttpURLConnection is set properly with getInstanceFollowRedirects() == true.

like image 43
Vladimir Mitev Avatar answered Oct 29 '22 17:10

Vladimir Mitev


When using the CommonsClientHttpRequestFactory (which uses HttpClient v3 underneath) you can override the postProcessCommonsHttpMethod method and set to follow redirects.

public class FollowRedirectsCommonsClientHttpRequestFactory extends CommonsClientHttpRequestFactory {

  @Override
  protected void postProcessCommonsHttpMethod(HttpMethodBase httpMethod) {
    httpMethod.setFollowRedirects(true);
  }
}

You can then use it like this (with optional, possibly preconfigured, HttpClient instance) and requests will follow the location headers in response:

RestTemplate restTemplate = new RestTemplate(
      new FollowRedirectsCommonsClientHttpRequestFactory());
like image 2
Mrkvozrout Avatar answered Oct 29 '22 18:10

Mrkvozrout