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。

相关推荐
清晓粼溪12 分钟前
SpringMVC-01:基础知识
java·spring
编程修仙1 小时前
第十一篇 Spring事务
xml·java·数据库·spring
jiayong233 小时前
Spring 框架完全指南
java·后端·spring
没有bug.的程序员3 小时前
Async Profiler:最精准的火焰图工具
java·jvm·spring·对象分配·async profiler
7哥♡ۣۖᝰꫛꫀꪝۣℋ3 小时前
Spring WebMVC及常用注释
java·数据库·spring
谷哥的小弟4 小时前
Spring Framework源码解析——AnnotationAwareOrderComparator
java·后端·spring·源码
谷哥的小弟4 小时前
Spring Framework源码解析——StringUtils
java·后端·spring·源码
Java天梯之路4 小时前
Spring IOC 核心源码解析
java·spring·源码
雨中飘荡的记忆4 小时前
Spring Data JPA详解
java·spring
雨中飘荡的记忆4 小时前
Spring Security详解
java·spring