1. 主要类¶
- DispatcherServlet
-
WebApplicationContext
-
RequestContextUtils
preHandle postHandle afterCompletion
可以对 response 进行干预 ResponseBodyAdvice RequestMappingHandlerAdapter
HandlerExceptionResolver 异常处理程序的 Resolver * SimpleMappingExceptionResolver * DefaultHandlerExceptionResolver * ResponseStatusExceptionResolver * ExceptionHandlerExceptionResolver
FormattingConversionServiceFactoryBean
View Resovler
LocalValidatorFactoryBean
能够用于 MVC 配置的机制有 * 实现 WebMvcConfigurer 接口,可以添加 * addFormatters * addInterceptors * addResourceHandlers * addCorsMappings * addViewControllers * addArgumentResolvers * addReturnValueHandlers * 通过 @InitBinder 注解
上边的 addXXX 中有个 yyyRegistry 的概念
2. Context Hierarchy¶
3. web.xml 中可以配置的参数¶
3.1 MVC Config¶
都可以配置哪些内容
- 使能 MVC 配置
- MVC Config API
- Type Conversion
- Validation
- Interceptors
- Content Types
- Message Converters
- View Controllers
- View Resolvers
- Static Resources
- Default Servlet
- Path Matching
- Advanced Java Config
- Advance XML Config
3.1.1 配置静态资源¶
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/public", "classpath:/static/")
.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)));
}
}
@Configuration
@EnableWebMvc
public class WebConfig {
}
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
}
3.1.2 错误处理¶
- 错误处理调用链
- 默认错误处理页
3.1.3 视图(View) 相关¶
核心类 * ViewResolver * View
ViewResolver * AbstractCachingViewResolver * UrlBasedViewResolver * InternalResourceViewResolver * FreeMarkerViewResolver * ContentNegotiatingViewResolver * BeanNameViewResolver
View 也可以多个组成 chain view resolvers
3.1.3.1 重定向*(Redirecting)¶
前缀 redirect:
,对应的 View 为 RedirectView
3.1.3.2 (转发)Forwarding¶
前缀 forward:
,
UrlBasedViewResolver RequestDispatcher.forward()
3.1.3.3 内容协商¶
3.1.3.4 本地化¶
RequestContext.getLocale()
org.springframework.web.servlet.i18n
可以根据以下纬度进行 locale 的解析 - Time Zone - Header Resolver - Cookie Resolver - Session Resolver - Locale Interceptor
3.1.3.5 主题¶
包: org.springframework.ui.context.ThemeSourc
ThemeResolver * FixedThemeResolver * SessionThemeResolver * CookieThemeResolver
org.springframework.ui.context.support.ResourceBundleThemeSource
3.1.3.6 Multipart Resolver¶
包 org.springframework.web.multipart
MultipartResolver * CommonsMultipartResolver * StandardServletMultipartResolver MultipartHttpServletRequest
3.2 CORS 跨域处理¶
- 每个
HandlerMapping
均可以配置自己的 CorsConfiguration;但通常有一个全局的 CORS 配置即可
@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...
}
}
3.2.1 支持条件定义接口¶
如下示例: 判断请求参数中是否包含 https://xxx.com/pets/1234?myParam=myValue
@GetMapping(path = "/pets/{petId}", params = "myParam=myValue")
public void findPet(@PathVariable String petId) {
// ...
}
如下示例,判断是否 HTTP header 包含 myHeader: myValue
@GetMapping(path = "/pets", headers = "myHeader=myValue")
public void findPet(@PathVariable String petId) {
// ...
}
3.2.1.1 @RequestParam 不是必须的¶
Note that use of @RequestParam is optional (for example, to set its attributes). By default, any argument that is a simple value type (as determined by BeanUtils#isSimpleProperty) and is not resolved by any other argument resolver, is treated as if it were annotated with @RequestParam.
3.2.1.2 @RequestHeader 可以作用到通用集合类型上 Map, MultiValueMap, or HttpHeaders¶
When an @RequestHeader annotation is used on a Map
, MultiValueMap , or HttpHeaders argument, the map is populated with all header values.
3.2.2 Data binding 和 Type conversion 的区别¶
- @ModelAttribute 可以作用到方法上、参数上
- @ModelAttribute(binding=false) 可以通过 binding=false 指定不进行参数绑定
- 可以通过 Valid 指定对参数是否进行校验
ResponseEntity && RequestEntity 表示 HTTP 响应、请求的完整实体,包括请求头、方法、body 等
3.3 1.10 视图技术¶
3.4 1.11 MVC 配置¶
@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.indentOutput(true)
.dateFormat(new SimpleDateFormat("yyyy-MM-dd"))
.modulesToInstall(new ParameterNamesModule());
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
}
}
4. 2. REST 客户端 (REST Client)¶
4.1 2.1 RestTemplate¶
从 Spring 5.0 开始,
RestTempalte
进入维护模式,后续可以使用WebClient
提供的更加现代,且支持同步、异步、流场景的 API
5. 3. 测试(Testing)¶
- Servlet API Mocks
- TestContext Framework
- Spring MVC Test
- Client-side REST
- WebTestClient
6. 4. Websockets¶
6.1 主要类¶
- @EnableWebSocket 开启 Websocket
- WebSocketHttpRequestHandler
- TextWebSocketHandler
- BinaryWebSocketHandler
- ConcurrentWebSocketSessionDecorator
- WebSocketConfigurer
- WebSocketHandlerRegistry
- HandshakeInterceptor
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myHandler(), "/myHandler");
}
@Bean
public WebSocketHandler myHandler() {
return new MyHandler();
}
}