Spring MVC(四)— CORS、HTTP缓存及MVC配置

Spring CORS 允许开发者配置哪些域可以访问其Web应用的资源。HTTP缓存是提高Web应用程序性能的一种重要技术。通过实现WebMvcConfigurer接口来对MVC容器进行配置。

1 CORS

Cross-Origin Resource Sharing,跨源资源共享。是一种基于HTTP头的机制。允许浏览器向不同源(domain、protocol、port)的服务器发出XMLHttpRequest请求,从而克服同源策略的限制。

图 CORS请求处理流程

1.1 AbstractHandlerMapping

在将请求映射到处理器后,会检查该请求的CORS信息并进行验证,如果通过则在响应中添加CORS相关的头信息。

图 AbstractHandlerMapping 的getHandler方法

|-------------------|----------------------------------------------------------------------|
| PreFlightHandler | CORS规范的一部分,处理CORS预检测(OPTIONS请求) |
| CorsProcessor | 对CORS请求进行处理。根据CORS配置信息,检查并验证CORS头信息,对响应进行处理。如果检测通过,则向响应头中添加CORS相关信息。 |
| CorsConfiguration | CORS配置信息。 |

表 处理cors请求的相关类

1.1.1 配置CORS信息

|------------------|--------------------------|
| origins | 允许的请求源。 |
| allowedHeaders | 在跨域请求中允许携带的请求头。 |
| exposeHeaders | 跨域请求响应中,应该暴露给前端JS代码的响应头。 |
| methods | 允许的请求方法。 |
| allowCredentials | 是否允许浏览器发送凭证(如cookies)。 |
| maxAge | 预检请求的缓存持续最大时长(以秒为单位)。 |

表 CORS的配置信息

有两种方式配置CORS信息:

  1. @CrossOrigin,可作用于类及方法级别。

  2. 在WebMvcConfigurer 实现类中,重写addCorsMappings方法。

  3. 通过CorsFilter 来配置。

    @Override
    public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**") // 为指定的路径模式启用跨源请求处理。
    .allowedOrigins("*"); // 允许所有请求源
    }

2 HTTP缓存

HTTP缓存可以显著地提升web应用程序的性能。主要依赖于Cache-Control响应头,以及后续的条件请求头(如Last-Modified和ETag)。

2.1 CacheControl

为响应创建Cache-Control头部信息。

Cache-Control 是HTTP协议中关于缓存的响应头,用于定义一个响应资源何时、如何被缓存及缓存时间。

|-----------------|-------------------------------------------------|
| private | 默认值,只能被单个用户缓存,不能被共享缓存。 |
| no-cache | 防止从缓存中返回过期的资源。每次请求时都需要对缓存进行验证(无论是否过期,验证缓存是否过期)。 |
| max-age | 资源在缓存中的最大生存时间,单位为秒。 |
| must-revalidate | 要求缓存的资源在过期后必须重新验证。 |
| no-store | 缓存不应存储有关客户端请求或服务器响应的任何内容。 |

表 Cache-Control 常见的取值

2.1.1 WebContentInterceptor

是Spring定义的一个拦截器。用于检查请求并准备响应。检查请求是否支持特定的方法,是否需要一个会话、并指定CacheControl构建器。

图 WebContentInterceptor的lookupCacheControl方法

2.1.2 ResponseEntity 设置缓存信息

ResponseEntity可以为单个处理器设置CacheControl 及ETag。

复制代码
@RestController
@RequestMapping("/cache")
public class CacheController {
    @GetMapping
    public ResponseEntity<String> getUser(WebRequest request, HttpServletResponse response, @RequestParam Long userId) {
        String user = getUser(userId);
        return ResponseEntity
                .ok()
                .cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS))
                .eTag(user.hashCode()+"")
                .body(user);
    }

    private String getUser(Long userId) { // 模拟从数据库取值
        return "user" + userId;
    }
}

3 常见的MVC配置

@EnableWebMvc 是一个用于启用Spring MVC配置的注解。通常与@Configuration注解一起使用。使用该注解时,会自动导入DelegatingWebMvcConfiguration类来对MVC做些默认的配置。

可以通过扩展WebMvcConfigurer 接口,来提供自定义的MVC配置,覆盖默认配置。

3.1 HttpMessageConverter

用于转换HTTP请求和响应的body。将请求体转换为Java对象,及将Java对象转换为响应体中的数据。

图 HttpMessageConverter UML

|-------------------------------------|--------------------------------------------------------------------------------------------|
| StringHttpMessageConverter | 将请求和响应体中的字符串与Java的String对象进行转换。 支持的媒体类型包括text/plain和所有其他文本类型。 |
| MappingJackson2HttpMessageConverter | 利用Jackson库将请求和响应体中的JSON数据与Java对象进行转换。 支持的媒体类型通常是application/json。 |
| FormHttpMessageConverter | 将表单数据转换为MultiValueMap<String,String>。 用于表单数据的转换,支持application/x-www.form-unlencoded媒体类型。 |

表 HttpMessageConverter 常见的实现

3.2 静态资源

WebMvcConfigurer允许开发者从基于Resource位置列表中方便地提供静态资源服务。

复制代码
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**") // 以/resources 开头的请求都会被映射为静态路径处理
            .addResourceLocations("classpath:/static/","/public") // 首先会在类路径下的static文件夹下查找文件,没找到则在/public路径下查找,可以指定多个查找路径
            .setCachePeriod(31556926) // 缓存周期,单位为秒
            .resourceChain(true)
            .addResolver(new VersionResourceResolver());
}

3.2.1 VersionResourceResolver

主要作用是解析带有版本信息的资源URL,并映射到实际的资源文件。

例如,有个静态资源文件,hello.txt,其版本是v1.0。那么对于的URL是:

/resources/hello.txt?v=v1.0。

相关推荐
天若有情6732 小时前
【java EE】IDEA 中创建或迁移 Spring 或 Java EE 项目的核心步骤和注意事项
后端·spring·java-ee·intellij-idea
雪域迷影3 小时前
C#中通过get请求获取api.open-meteo.com网站的天气数据
开发语言·http·c#·get
钱多多_qdd4 小时前
基础篇:IoC(三):Bean实例化策略InstantiationStrategy
java·spring
安冬的码畜日常7 小时前
【JUnit实战3_27】第十六章:用 JUnit 测试 Spring 应用:通过实战案例深入理解 IoC 原理
spring·观察者模式·设计模式·单元测试·ioc·依赖注入·junit5
2501_915918417 小时前
HTTP抓包工具推荐,Fiddler使用教程、代理设置与调试技巧详解(含HTTPS配置与实战案例)
http·ios·小程序·https·fiddler·uni-app·webview
敲代码的嘎仔9 小时前
JavaWeb零基础学习Day6——JDBC
java·开发语言·sql·学习·spring·单元测试·maven
Pocker_Spades_A9 小时前
Python快速入门专业版(五十四):爬虫基石:HTTP协议全解析(从请求到响应,附Socket模拟请求)
爬虫·python·http
天玺-vains11 小时前
借助Github Action实现通过 HTTP 请求触发邮件通知
网络协议·http·github
程序猿小蒜12 小时前
基于springboot的校园社团信息管理系统开发与设计
java·前端·spring boot·后端·spring
兔兔爱学习兔兔爱学习12 小时前
Spring Al学习9:模型上下文协议(MCP)
java·学习·spring