CORS跨域资源共享(二):详解Spring MVC对CORS支持的相关类和API【享学Spring MVC】(下)

简介: CORS跨域资源共享(二):详解Spring MVC对CORS支持的相关类和API【享学Spring MVC】(下)

CorsFilter

Spring4.2之前一般自己去实现一个这样的Filter来处理,4.2之后框架提供了内置支持。

Reactive的叫org.springframework.web.cors.reactive.CorsWebFilter


// @since 4.2
public class CorsFilter extends OncePerRequestFilter {
  private final CorsConfigurationSource configSource;
  // 默认使用的DefaultCorsProcessor,当然你也可以自己指定
  private CorsProcessor processor = new DefaultCorsProcessor();
  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    // 只处理跨域请求
    if (CorsUtils.isCorsRequest(request)) {
      // Spring这里有个bug:因为它并不能保证configSource肯定被初始化了
      CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
      if (corsConfiguration != null) {
        boolean isValid = this.processor.processRequest(corsConfiguration, request, response);
        // 若处理后返回false,或者该请求本身就是个Options请求,那后面的Filter也不要处理了~~~~~
        if (!isValid || CorsUtils.isPreFlightRequest(request)) {
          return;
        }
      }
    }
    filterChain.doFilter(request, response);
  }
}


它的工作完全委托给CorsProcessor去处理的。此Filter可以与DelegatingFilterProxy一起使用,以帮助初始化且可以使用Spring容器内的Bean。注意CorsFilter在框架内部默认是木有配置的,若有需要请自行配置~


CorsFilter属于jar包内的过滤器,在没有web.xml环境下如何配置呢?详见下个章节的示例

@CrossOrigin


Spring MVC提供了此注解来帮助你解决CORS跨域问题,比你使用Filter更加的方便,且能实现更加精细化的控制(一般可以和CorsFilter一起来使用,效果更佳)。

Spring Web MVC和Spring WebFlux在RequestMappingHandlerMapping里都是支持此注解的,该注解配置参数的原理可参考CorsConfiguration


// @since 4.2 可使用在类上和方法上
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
  // 下面4个属性在5.0后都被此方法所代替 因为此方法默认会被执行
  /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
  @Deprecated
  String[] DEFAULT_ORIGINS = { "*" };
  @Deprecated
  String[] DEFAULT_ALLOWED_HEADERS = { "*" };
  @Deprecated
  boolean DEFAULT_ALLOW_CREDENTIALS = false;
  @Deprecated
  long DEFAULT_MAX_AGE = 1800;
  // 若需要通配,可写*
  @AliasFor("origins")
  String[] value() default {};
  @AliasFor("value")
  String[] origins() default {};
  String[] allowedHeaders() default {};
  String[] exposedHeaders() default {};
  RequestMethod[] methods() default {};
  String allowCredentials() default "";
  long maxAge() default -1; // 负值意味着不生效 By default this is set to {@code 1800} seconds (30 minutes)
}


此注解可以标注在Controller上和方法上,若都有标注将会有combine的效果。


CorsRegistry / CorsRegistration


这两个类是Spring MVC提供出来便于进行global全局配偶的,它是基于URL pattern配置的。


public class CorsRegistry {
  // 保存着全局的配置,每个CorsRegistration就是URL pattern和CorsConfiguration配置
  private final List<CorsRegistration> registrations = new ArrayList<>();
  // 像上面List添加一个全局配置(和pathPattern绑定)
  // 它使用的是new CorsRegistration(pathPattern)
  // 可见使用配置是默认配置:new CorsConfiguration().applyPermitDefaultValues()
  // 当然它CorsRegistration return给你了,你还可以改(配置)的~~~~
  public CorsRegistration addMapping(String pathPattern) {
    CorsRegistration registration = new CorsRegistration(pathPattern);
    this.registrations.add(registration);
    return registration;
  }
  // 这个就比较简单了:把当前List专程Map。key就是PathPattern~~~~
  protected Map<String, CorsConfiguration> getCorsConfigurations() {
    Map<String, CorsConfiguration> configs = new LinkedHashMap<>(this.registrations.size());
    for (CorsRegistration registration : this.registrations) {
      configs.put(registration.getPathPattern(), registration.getCorsConfiguration());
    }
    return configs;
  }
}


对于CorsRegistration这个类,它就是持有pathPattern和CorsConfiguration config两个属性,它特特点是提供了allowedMethods/allowedHeaders...等方法,提供钩子方便我们对CorsConfiguration进行配置,源码很简单略。


这两个类虽然简单,但是在@EnableWebMvc里扩展配置时使用得较多,参见下个章节对WebMvcConfigurer扩展使用和配置


相关阅读

CORS跨域资源共享(一):模拟跨域请求以及结果分析,理解同源策略【享学Spring MVC】

CORS跨域资源共享(二):详解Spring MVC对CORS支持的相关类和API【享学Spring MVC】

CORS跨域资源共享(三):@CrossOrigin/CorsFilter处理跨域请求示例,原理分析【享学Spring MVC】


总结


本文内容主要介绍Spring MVC它对CORS支持的那些类,为我们生产是灵活的使用Spring MVC解决CORS问题提供理论基础。下个章节也是本系列的最后一个章节,将具体介绍Spring MVC中对CORS的实践。

相关文章
|
3月前
|
安全 API PHP
PHP中实现CORS跨域资源共享的方法
通过这种方式,你可以在PHP应用中灵活地实现CORS,以支持跨域Web应用的需求。
276 15
|
3月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
4月前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
3976 2
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
|
9月前
|
存储 人工智能 Java
Spring AI与DeepSeek实战四:系统API调用
在AI应用开发中,工具调用是增强大模型能力的核心技术,通过让模型与外部API或工具交互,可实现实时信息检索(如天气查询、新闻获取)、系统操作(如创建任务、发送邮件)等功能;本文结合Spring AI与大模型,演示如何通过Tool Calling实现系统API调用,同时处理多轮对话中的会话记忆。
1964 57
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
412 2
|
6月前
|
SQL Java 数据库连接
Spring、SpringMVC 与 MyBatis 核心知识点解析
我梳理的这些内容,涵盖了 Spring、SpringMVC 和 MyBatis 的核心知识点。 在 Spring 中,我了解到 IOC 是控制反转,把对象控制权交容器;DI 是依赖注入,有三种实现方式。Bean 有五种作用域,单例 bean 的线程安全问题及自动装配方式也清晰了。事务基于数据库和 AOP,有失效场景和七种传播行为。AOP 是面向切面编程,动态代理有 JDK 和 CGLIB 两种。 SpringMVC 的 11 步执行流程我烂熟于心,还有那些常用注解的用法。 MyBatis 里,#{} 和 ${} 的区别很关键,获取主键、处理字段与属性名不匹配的方法也掌握了。多表查询、动态
197 0
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
242 4
|
10月前
|
安全 API Swift
如何在苹果内购开发中获取App Store Connect API密钥-共享密钥理解内购安全-优雅草卓伊凡
如何在苹果内购开发中获取App Store Connect API密钥-共享密钥理解内购安全-优雅草卓伊凡
829 15
如何在苹果内购开发中获取App Store Connect API密钥-共享密钥理解内购安全-优雅草卓伊凡
|
12月前
|
SQL Java 数据库连接
对Spring、SpringMVC、MyBatis框架的介绍与解释
Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
720 29
|
9月前
|
前端开发 IDE Java
Spring MVC 中因导入错误的 Model 类报错问题解析
在 Spring MVC 或 Spring Boot 开发中,若导入错误的 `Model` 类(如 `ch.qos.logback.core.model.Model`),会导致无法解析 `addAttribute` 方法的错误。正确类应为 `org.springframework.ui.Model`。此问题通常因 IDE 自动导入错误类引起。解决方法包括:删除错误导入、添加正确包路径、验证依赖及清理缓存。确保代码中正确使用 Spring 提供的 `Model` 接口以实现前后端数据传递。
314 0