使用Spring Web MVC,开发者可以直接访问官方文档Spring Web MVC文档Version 5.2.1.RELEASE,本文及Spring MVC系列文章都参考于此文档及源码。
这一节来看Spring MVC更多使用方法。
1. CORS
可以看到文档是怎么介绍的:
For security reasons, browsers prohibit AJAX calls to resources outside the current origin. For example, you could have your bank account in one tab and evil.com in another. Scripts from evil.com should not be able to make AJAX requests to your bank API with your credentials — for example withdrawing money from your account!
Cross-Origin Resource Sharing (CORS) is a W3C
specification implemented by most browsers that lets you specify what kind of cross-domain requests are authorized, rather than using less secure and less powerful workarounds based on IFRAME
or JSONP
.
浏览器禁止跨域,可以使用W3C规范的CORS,而不是使用安全性低,功能弱的变通方法IFRAME或者JSONP。
- @CrossOrigin
可以使用@CrossOrigin
允许跨域访问,例如:@CrossOrigin(maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @CrossOrigin("https://domain2.com") @GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } @DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ... } }
- 全局配置
可以使用WebMvcConfigurer全局配置如:
还可以xml进行全局配置@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("https://domain2.com") .allowedMethods("PUT", "DELETE") .allowedHeaders("header1", "header2", "header3") .exposedHeaders("header1", "header2") .allowCredentials(true).maxAge(3600); // Add more mappings... } }
<mvc:cors> <mvc:mapping path="/api/**" allowed-origins="https://domain1.com, https://domain2.com" allowed-methods="GET, PUT" allowed-headers="header1, header2, header3" exposed-headers="header1, header2" allow-credentials="true" max-age="123" /> <mvc:mapping path="/resources/**" allowed-origins="https://domain1.com" /> </mvc:cors>
- 拦截器实现
CorsConfiguration config = new CorsConfiguration(); // Possibly... // config.applyPermitDefaultValues() config.setAllowCredentials(true); config.addAllowedOrigin("https://domain1.com"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); CorsFilter filter = new CorsFilter(source);
2. URI
可以是用
UriComponentsBuilder
创建UriComponents
,URI
:UriComponents uriComponents = UriComponentsBuilder .fromUriString("https://example.com/hotels/{hotel}") .queryParam("q", "{q}") .encode() .build(); URI uri = uriComponents.expand("Westin", "123").toUri();
也可以使用
UriBuilder
,UriBuilderFactory
,UriComponentsBuilder
实现了UriBuilder
:String baseUrl = "https://example.org"; DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl); factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES);
使用
RestTemplate
或者WebClient
操作URI:RestTemplate restTemplate = new RestTemplate(); restTemplate.setUriTemplateHandler(factory); WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
3. Asyn
Spring MVC提供了异步接口使用。
DeferredResult
@GetMapping("/quotes") @ResponseBody public DeferredResult<String> quotes() { DeferredResult<String> deferredResult = new DeferredResult<String>(); // Save the deferredResult somewhere.. return deferredResult; } // From some other thread... deferredResult.setResult(result);
Callable
@PostMapping public Callable<String> processUpload(final MultipartFile file) { return new Callable<String>() { public String call() throws Exception { // ... return "someView"; } }; }
4. 缓存
CacheControl
提供对配置与Cache-Control
标头相关的设置的支持。
// Cache for an hour - "Cache-Control: max-age=3600"
CacheControl ccCacheOneHour = CacheControl.maxAge(1, TimeUnit.HOURS);
// Prevent caching - "Cache-Control: no-store"
CacheControl ccNoStore = CacheControl.noStore();
// Cache for ten days in public and private caches,
// public caches should not transform the response
// "Cache-Control: max-age=864000, public, no-transform"
CacheControl ccCustom = CacheControl.maxAge(10, TimeUnit.DAYS).noTransform().cachePublic();
@GetMapping("/book/{id}")
public ResponseEntity<Book> showBook(@PathVariable Long id) {
Book book = findBook(id);
String version = book.getVersion();
return ResponseEntity
.ok()
.cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS))
.eTag(version) // lastModified is also available
.body(book);
}