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信息:
- @CrossOrigin,可作用于类及方法级别。
- 在WebMvcConfigurer 实现类中,重写addCorsMappings方法。
- 通过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。