Рубрики
Без рубрики

Поток и сердечник пружинного полотна

Краткое и практическое руководство по работе с потоком ШНУРА и пружинного полотна.

Автор оригинала: baeldung.

1. Обзор

В предыдущем посте мы узнали о спецификации совместного использования ресурсов между источниками (CORS) и о том , как ее использовать в Spring.

В этом кратком руководстве мы настроим аналогичную конфигурацию CORS с помощью Spring 5 WebFlux framework .

Прежде всего, мы посмотрим, как мы можем включить этот механизм в API на основе аннотаций.

Затем мы проанализируем, как включить его во всем проекте в качестве глобальной конфигурации или с помощью специального WebFilter .

2. Включение CORS для аннотированных элементов

Пружина обеспечивает @CrossOrigin аннотация для включения запросов CORS на классы контроллеров и/или методы обработчиков.

2.1. Использование @CrossOrigin в методе обработчика запросов

Давайте добавим эту аннотацию к нашему сопоставленному методу запроса:

@CrossOrigin
@PutMapping("/cors-enabled-endpoint")
public Mono corsEnabledEndpoint() {
    // ...
}

Мы будем использовать WebTestClient (как мы объяснили в разделе ‘4. Тестирование этого поста ) для анализа ответа, который мы получаем от этой конечной точки:

ResponseSpec response = webTestClient.put()
  .uri("/cors-enabled-endpoint")
  .header("Origin", "http://any-origin.com")
  .exchange();

response.expectHeader()
  .valueEquals("Access-Control-Allow-Origin", "*");

Кроме того, мы можем опробовать предполетный запрос, чтобы убедиться, что конфигурация CORS работает должным образом:

ResponseSpec response = webTestClient.options()
  .uri("/cors-enabled-endpoint")
  .header("Origin", "http://any-origin.com")
  .header("Access-Control-Request-Method", "PUT")
  .exchange();

response.expectHeader()
  .valueEquals("Access-Control-Allow-Origin", "*");
response.expectHeader()
  .valueEquals("Access-Control-Allow-Methods", "PUT");
response.expectHeader()
  .exists("Access-Control-Max-Age");

Аннотация @CrossOrigin имеет следующую конфигурацию по умолчанию:

  • Разрешает все источники (это объясняет значение ” * ” в заголовке ответа)
  • Разрешает все заголовки
  • Все методы HTTP, сопоставленные методом обработчика, разрешены
  • Учетные данные не включены
  • Значение “Максимальный возраст” составляет 1800 секунд (30 минут)

Однако любое из этих значений может быть переопределено с помощью параметров аннотаций.

2.2. Использование @CrossOrigin на контроллере

Эта аннотация также поддерживается на уровне класса, и она повлияет на все его методы.

В случае, если конфигурация уровня класса не подходит для всех наших методов, мы можем аннотировать оба элемента, чтобы получить желаемый результат:

@CrossOrigin(value = { "http://allowed-origin.com" },
  allowedHeaders = { "Baeldung-Allowed" },
  maxAge = 900
)
@RestController
public class CorsOnClassController {

    @PutMapping("/cors-enabled-endpoint")
    public Mono corsEnabledEndpoint() {
        // ...
    }

    @CrossOrigin({ "http://another-allowed-origin.com" })
    @PutMapping("/endpoint-with-extra-origin-allowed")
    public Mono corsEnabledWithExtraAllowedOrigin() {
        // ...
    }

    // ...
}

3. Включение CORS в глобальной конфигурации

Мы также можем определить глобальную конфигурацию CORS, переопределив addCorsMappings() способ получения WebFluxConfigurer реализация.

Кроме того, реализация нуждается в аннотации @EnableWebFlux для импорта конфигурации веб-потока Spring в обычном приложении Spring. Если мы используем Spring Boot, то эта аннотация нужна нам только в том случае, если мы хотим переопределить автоматическую настройку:

@Configuration
@EnableWebFlux
public class CorsGlobalConfiguration implements WebFluxConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry corsRegistry) {
        corsRegistry.addMapping("/**")
          .allowedOrigins("http://allowed-origin.com")
          .allowedMethods("PUT")
          .maxAge(3600);
    }
}

В результате мы включаем обработку запросов из разных источников для этого конкретного шаблона пути.

Конфигурация по умолчанию аналогична конфигурации @CrossOrigin , но разрешены только методы GET , HEAD и POST .

Мы также можем объединить эту конфигурацию с локальной:

  • Для атрибутов с несколькими значениями результирующая конфигурация CORS будет дополнением каждой спецификации
  • С другой стороны, локальные значения будут иметь приоритет над глобальными для однозначных значений

Однако использование этого подхода неэффективно для функциональных конечных точек.

4. Включение CORS с помощью веб-фильтра

Лучший способ включить CORS на функциональных конечных точках-это использовать Вебфильтр .

Как мы видели в этом посте , мы можем использовать Веб-фильтр s для изменения запросов и ответов, сохраняя при этом реализацию конечных точек нетронутой.

Пружина обеспечивает встроенный CorsWebFilter чтобы легко справляться с конфигурациями перекрестного происхождения:

@Bean
CorsWebFilter corsWebFilter() {
    CorsConfiguration corsConfig = new CorsConfiguration();
    corsConfig.setAllowedOrigins(Arrays.asList("http://allowed-origin.com"));
    corsConfig.setMaxAge(8000L);
    corsConfig.addAllowedMethod("PUT");
    corsConfig.addAllowedHeader("Baeldung-Allowed");

    UrlBasedCorsConfigurationSource source =
      new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", corsConfig);

    return new CorsWebFilter(source);
}

Это также эффективно для аннотированных обработчиков, но его нельзя комбинировать с более мелкозернистой конфигурацией @CrossOrigin .

Мы должны иметь в виду, что конфигурация Cors не имеет конфигурации по умолчанию.

Таким образом, если мы не определим все соответствующие атрибуты, реализация CORS будет в значительной степени ограничительной.

Простым способом установки значений по умолчанию является использование применить значения Разрешения По Умолчанию() метод на объекте.

5. Заключение

В заключение мы ознакомились с очень короткими примерами того, как включить CORS в нашем веб-сервисе на основе потока.

Мы видели разные подходы, поэтому все, что нам сейчас нужно сделать, это проанализировать, какой из них лучше всего соответствует нашим требованиям.

Мы можем найти множество примеров в нашем репозитории GitHub , а также тестовые случаи, в которых мы анализируем большинство крайних случаев, связанных с этой темой.