Выполните перенаправление 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 автоматически будет соблюдаться. Я ошибаюсь в этом предположении? Теперь мне нужно снять это местоположение и повторно запросить?

Ответ 1

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

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

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

    ...

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

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

Устанавливает, будут ли перенаправления HTTP (запросы с кодом ответа 3xx) за этим автоматически следует {@code HttpURLConnection} пример.

Значение по умолчанию происходит от followRedirects, значение по умолчанию равно true.

Ответ 2

При использовании CommonsClientHttpRequestFactory (который использует 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());

Ответ 3

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

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

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

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