Выполнить 302 редирект с помощью 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

У меня создалось впечатление, что 302-й будет автоматически следовать. Я ошибаюсь в этом предположении? Теперь мне нужно выбрать это место и повторно запросить?


person techie.brandon    schedule 02.04.2015    source источник
comment
ты нашел ответ?   -  person Afroz Shaikh    schedule 01.09.2016


Ответы (3)


Использование реализации по умолчанию ClientHttpRequestFactory - SimpleClientHttpRequestFactory - поведение по умолчанию - следовать URL-адресу заголовка местоположения (для ответов с кодами состояния 3xx) - но только если первоначальный запрос был GETrequest.

Подробности можно найти в этом классе - поиск следующего метода:

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

    ...

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

Вот соответствующий документ-комментарий метода HttpURLConnection.setInstanceFollowRedirects:

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.

person fateddy    schedule 02.04.2015
comment
При условии, что я использую getForEntity, предполагается запрос GET. Я пошел дальше и обеспечил использование SimpleClientHttpRequestFactory в restTemplate с тем же результатом. Перейдем к выделенному вами коду и посмотрим, что происходит. - person techie.brandon; 03.04.2015
comment
Поскольку ваш ответ содержит заголовок location, он сообщает вам, что перенаправления не было. В противном случае ответ будет содержать результат самого последнего полученного ответа. Единственное, что может заключаться в том, что статус ответа не является 3xx - заголовок местоположения игнорируется. Сначала проверьте код состояния ответа (response.getStatusCode()). - person fateddy; 03.04.2015
comment
Я сделал new RestTemplate(new SimpleClientHttpRequestFactory() { protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { super.prepareConnection(connection, httpMethod); connection.setInstanceFollowRedirects(false); } });, чтобы отключить перенаправление - person mzzzzb; 07.04.2016
comment
Следует только одно перенаправление - person Skeeve; 09.11.2018

Вы пытаетесь перенаправить с одного протокола на другой, например с http на https или наоборот? В таком случае автоматическое перенаправление работать не будет. См. Этот комментарий: URLConnection не следует за перенаправлением

После обсуждения между инженерами Java Networking возникло мнение, что мы не должны автоматически выполнять перенаправление с одного протокола на другой, например, с http на https и наоборот, это может иметь серьезные последствия для безопасности.

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

В противном случае, если вы отлаживаете код RestTemplate, вы увидите, что по умолчанию HttpURLConnection правильно установлен с getInstanceFollowRedirects() == true.

person Vladimir Mitev    schedule 18.01.2019

При использовании CommonsClientFrameHttp: (который использует HttpClient v3 ниже) вы можете переопределить postProcessCommonsHttpMethod и настроен на выполнение переадресации.

public class FollowRedirectsCommonsClientHttpRequestFactory extends CommonsClientHttpRequestFactory {

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

Затем вы можете использовать его следующим образом (с необязательным, возможно, предварительно настроенным экземпляром HttpClient), и запросы будут следовать за заголовками location в ответ:

RestTemplate restTemplate = new RestTemplate(
      new FollowRedirectsCommonsClientHttpRequestFactory());
person Mrkvozrout    schedule 07.03.2017