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。

相关推荐
CXDNW15 分钟前
【网络篇】计算机网络——应用层详述(笔记)
服务器·笔记·计算机网络·http·web·cdn·dns
秋夫人2 小时前
http cache-control
网络·网络协议·http
叶北辰CHINA2 小时前
nginx反向代理,负载均衡,HTTP配置简述(说人话)
linux·运维·nginx·http·云原生·https·负载均衡
潘多编程3 小时前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring
_阿伟_3 小时前
SpringMVC
java·spring
小白学大数据4 小时前
User-Agent在WebMagic爬虫中的重要性
开发语言·爬虫·http
GodK7777 小时前
HTTPS 的加密流程
网络协议·http·https
杨半仙儿还未成仙儿9 小时前
Spring框架:Spring Core、Spring AOP、Spring MVC、Spring Boot、Spring Cloud等组件的基本原理及使用
spring boot·spring·mvc
麻辣韭菜12 小时前
网络基础 【HTTP】
网络·c++·http
攸攸太上13 小时前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway