Включить Cors с помощью Spring 3.0.4

Я использую Java Spring 3.0.4 (не могу обновиться из-за некоторых требований), и мне нужно включить Cors, чтобы мой интерфейс мог общаться с моим сервером.

Мой сервер — это угловое приложение, работающее на: http://локальный:4200/домашний

Я пробовал следующее без везения:

public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
public static final String METHODS_NAME = "Access-Control-Allow-Methods";
public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
public static final String MAX_AGE_NAME = "Access-Control-Max-Age";

@PreAuthorize("hasRole('ADMIN')")
@RequestMapping(value = "/data", method=RequestMethod.GET)
public void serverSide(Model model,  HttpServletRequest request, HttpServletResponse response) throws IOException{

    response.setContentType("application/json");
    response.setHeader("Cache-Control", "no-store");

    response.setHeader(CREDENTIALS_NAME, "true");
    response.setHeader(ORIGIN_NAME, "http://localhost:4200");
    response.setHeader(METHODS_NAME, "GET, OPTIONS, POST, PUT, DELETE");
    response.setHeader(HEADERS_NAME, "Origin, X-Requested-With, Content-Type, Accept");
    response.setHeader(MAX_AGE_NAME, "3600");

    PrintWriter out = response.getWriter();

    out.print("TEST!!");
}       

Вы пытались добавить @CrossOrigin к методу контроллера?

Madhu Bhat 26.03.2019 18:39

Я считаю, что аннотация была добавлена ​​​​в Spring 3.2, но да, я пробовал, и она жалуется, что аннотация не имеет определения. @MadhuBhat

sbattou 26.03.2019 18:43

Вы случайно не используете Apache Tomcat? Как вы развертываете свое приложение?

Karol Dowbecki 26.03.2019 18:43

@KarolDowbecki да, я использую Apache Tomcat, но я не совсем уверен, как развертываются наши приложения (очень новичок в этой команде)

sbattou 26.03.2019 18:46

@sbattou, вы можете попробовать любой из ответов здесь stackoverflow.com/questions/32319396/…?

Madhu Bhat 26.03.2019 18:51

@MadhuBhat Эти ответы будут работать в более поздних версиях Spring. я пробовал и не повезло

sbattou 26.03.2019 19:07

Ответ @sbattou с Filter должен работать. Если вы удалите аннотацию @Component. Вам также нужно будет добавить соответствующие записи в web.xml

Ivan 26.03.2019 19:45

@ Иван, не могли бы вы привести пример кода? Не совсем уверен, что вы имеете в виду, добавляя соответствующие записи в web.xml

sbattou 26.03.2019 20:33
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
8
3 734
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете расширить Filter интерфейс.

public class CORSFilter implements Filter {

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      HttpServletResponse httpResponse = (HttpServletResponse) response;
      httpResponse.addHeader("Access-Control-Allow-Origin", "*");
      httpResponse.addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, OPTIONS");
      httpResponse.setHeader("Access-Control-Allow-Headers", "X-Requested-With, X-Auth-Token");       chain.doFilter(request, response);
  }

  @Override
  public void destroy() {

  }
}

И тогда вам нужно зарегистрировать фильтр в web.xml

<filter>
    <filter-name>cors</filter-name>
    <filter-class>com.yourpackage.CORSFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>cors</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Я действительно ценю это, нужно ли мне вызывать класс CorsFilter из моих контроллеров или файл web.xml в основном будет применять его для любой операции CRUD?

sbattou 27.03.2019 01:14

Он должен применяться к каждому URL-адресу в этом веб-приложении, поскольку фильтр сопоставляется с /* URL-адресом.

Ivan 27.03.2019 01:19

По-прежнему возникает ошибка SEC7120: Origin локальный: 4200 не найден в заголовке Access-Control-Allow-Origin. Я действительно думал, что это сработает, есть другие предложения?

sbattou 27.03.2019 13:40

Попробуйте заменить "Access-Control-Allow-Origin", "*" на "Access-Control-Allow-Origin", "http://localhost:4200"

Ivan 27.03.2019 14:01

Оказывается, был кусок кода, который перенаправлял мой запрос, как только я его отключил, все заработало!

sbattou 27.03.2019 15:33

Мне любопытно, почему вы используете addHeader для первых двух заголовков и setHeader только для Access-Control-Allow-Headers? Спасибо.

user1491636 03.02.2020 22:25

Вы можете включить CORS, создав Interceptor. Пожалуйста, выполните следующие шаги:

  1. Создайте перехватчик, расширив ОбработчикПерехватчикАдаптер

    public class CorsInterceptor extends HandlerInterceptorAdapter {
    
        public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
        public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
        public static final String METHODS_NAME = "Access-Control-Allow-Methods";
        public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
        public static final String MAX_AGE_NAME = "Access-Control-Max-Age";
    
       @Override
       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
          Object handler) throws Exception {
          response.setHeader(CREDENTIALS_NAME, "true");
          response.setHeader(ORIGIN_NAME, "http://localhost:4200");
          response.setHeader(METHODS_NAME, "GET, OPTIONS, POST, PUT, DELETE");
          response.setHeader(HEADERS_NAME, "Origin, X-Requested-With, Content-Type, 
            Accept");
          response.setHeader(MAX_AGE_NAME, "3600");
          return true;
      }
    
    }
    
  2. Зарегистрируйте созданный выше перехватчик в вашей веб-конфигурации.

    public class WebConfig extends WebMvcConfigurerAdapter {
    
      @Override
      public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CorsInterceptor());
      }
     // continue if any ..
    }
    
  3. Вышеупомянутое отлично работает для запросов GET, но для любого другого запроса модификации (POST, DELETE, PUT) браузер отправит предварительный запрос OPTIONS, который SpringMVC игнорирует. Итак, вы должны отправить запрос Options. Вы можете добавить dispatchOptionRequest к веб.xml следующим образом:

    <servlet>
        <servlet-name>servletName</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
         <param-name>dispatchOptionsRequest</param-name>
         <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    

Надеюсь это поможет! Спасибо.

Спасибо, что нашли время, чтобы опубликовать ответ. Должен ли я создавать класс веб-конфигурации, потому что в моем приложении его нет?

sbattou 27.03.2019 01:12

Я все еще использую Spring 3.0.5, нужно ли мне добавлять «CorsInterceptor» или «WebConfig» в любом месте XML-файла в качестве конфигурации, или Spring автоматически загрузит эти классы при запуске?

arunan 08.02.2021 09:24

С WebMVC это возможно и у меня работает. Попробуйте это, но если вы используете весеннюю безопасность, мне может потребоваться обновить ответ.

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfiguration implements WebMvcConfigurer {

private static final String HTTP_LOCALHOST_4200 = "http://localhost:4200";
private static final String GET = "GET";
private static final String POST = "POST";
private static final String PUT = "PUT";
private static final String DELETE = "DELETE";
private static final String HEAD = "HEAD";

@Override
public void addCorsMappings(CorsRegistry registry) {

    registry.addMapping("/**")
            .allowedOrigins(
                    HTTP_LOCALHOST_4200).allowedMethods(GET, POST, PUT, DELETE, 
  HEAD).allowCredentials(true);
 }
 }

CorsConfiguration недоступен весной 3.0

clairerb6 25.09.2019 04:46

addCorsMappings с весны 4.2

Joon 03.05.2020 11:20

Другие вопросы по теме