1、SpringMvc自动配置
Spring Boot 为SpringMvc提供了自动配置。
自动配置包含Spring的以下特征:
(1)视图解析器ContentNegotiatingViewResolver或BeanNameViewResolver。
(2)支持静态文件,包含对WebJar支持。
(3)自动注册转换器Converter、GenericConverter、Formatter。
(4)支持HttpMessageConverters(转换request、response的数据格式)
(5)注册MessageCodesResolver(转换错误代码)
(6)支持静态index.html
(7)支持Favicon
(8)支持自动使用数据绑定器ConfigurableWebBindingInitializer
如果你想保持上述的特征并加入SpringMvc的其他配置(如interceptors、formatters、view controllers等),你要加入你自己的带有@Configuration注解的WebMvcConfigurerAdapter,且要有注解@EnableWebMvc。如果你想提供常用的句柄如RequestMappingHandlerMapping、RequestMappingHandlerAdapter、ExceptionHandlerExceptionResolver,你可以定义一个WebMvcRegistrationsAdapter来提供这样的组件(component)。
2、HttpMessageConverters
SpringMvc利用HttpMessageConverter接口来转换HTTP request和response。对象会被自动转换为JSON(使用Jackson),或者XML(用Jackson XML或JAXB)。字符串通常默认UTF-8编码。
import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.context.annotation.*; import org.springframework.http.converter.*; @Configuration public class MyConfiguration { @Bean public HttpMessageConverters customConverters() { HttpMessageConverter<?> additional = ... HttpMessageConverter<?> another = ... return new HttpMessageConverters(additional, another); } }
任何Context中定义的HttpMessageConverter将会被添加到converters列表中。
3、JSON序列化和反序列化
如果你用Jackson进行数据序列化和反序列化,你可能会想建立自己的工具。其实Spring提供@JsonComponent来使对应类(实现serializers/deserializers接口)的Bean可以直接转换为JSON。也可以对内部类为serializers/deserializers的类进行注解。
import java.io.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import org.springframework.boot.jackson.*; @JsonComponent public class Example { public static class Serializer extends JsonSerializer<SomeObject> { // ... } public static class Deserializer extends JsonDeserializer<SomeObject> { // ... } }
所有@JsonComponent注解的beans会自动被Jackson注册。
4、MessageCodesResolver
MessageCodesResolver可以将错误代码转换为错误信息。只要你设置spring.mvc.message-codes-resolver.format的值为PREFIX_ERROR_CODE或POSTFIX_ERROR_COD(DefaultMessageCodesResolver.Format中的枚举),Spring Boot 会帮你创建一个。
5、静态文件区
Spring Boot 会默认的classpath或应用根目录下的/static(或者/public、/resources、/META-INF/resources)视为静态文件区。他默认使用Spring Mvc的ResourceHttpRequestHandler,你可以通过在自己的WebMvcConfigurerAdapter添加一个并重写addResourceHandlers实现修改默认的。
默认的,资源文件会匹配/**,你可以通过spring.mvc.static-path-pattern来设置,例如,设置resource下的所有文件为静态可设置为:
spring.mvc.static-path-pattern=/resources/**
你也可以通过设置spring.resources.static-locations的值来定制静态资源区。
Spring Boot还支持WebJar目录,/webjars/**下的任何以WebJar形式打包的文件都会被以jar形式来获取。
Spring Boot支持对静态文件进行版本管理,例如我们加入webjars-locator依赖后,"/webjars/jquery/dist/jquery.min.js"文件将会以地址"/webjars/jquery/x.y.z/dist/jquery.min.js"进行访问,"x.y.z"是WebJar的版本。
如果你使用JBoss,你要用webjars-locator-jboss-vfs依赖代替webjars-locator依赖。某则你的/wenjars/**会一直报404。
可以通过以下配置来配置缓存碎片,有效地在URL上加入文件区哈希码,如<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>
spring.resources.chain.strategy.content.enabled=true spring.resources.chain.strategy.content.paths=/**
fixed策略将会只给URL增加版本但是不改变它的名称。
spring.resources.chain.strategy.content.enabled=true spring.resources.chain.strategy.content.paths=/** spring.resources.chain.strategy.fixed.enabled=true spring.resources.chain.strategy.fixed.paths=/js/lib/ spring.resources.chain.strategy.fixed.version=v12
上面的配置中,/js/lib/mymodule.js会变为/v12/js/lib/mymodule.js。
6、favicon.ico
Spring Boot 会自动在静态文件区根目录和classpath根目录寻找favicon.ico文件,一旦找到,将之作为图标。
7、ConfigurableWebBindingInitializer
SpringMvc通过使用WebBindingInitializer初始化一个WebDataBinder来处理特定的请求。你可以建立自己的ConfigurableWebBindingInitializer Bean,Spring Boot将会自动配置SpringMvc来使用它。
8、模板引擎
SpringBoot会自动使用下列模板引擎
FreeMaker
Groovy
Thymeleaf
Mustache
模板文件通常放在classpath*:templates目录下。
9、错误处理
Spring Boot 提供/error 匹配所有的错误信息使得它们可视化。对于机器客户端,页面返回的是一个JSON字符串,包含状态和异常信息;对于浏览器客户端,页面返回的是一个错误数据渲染的错误页面(你可以通过自己定义/error controller来覆盖)。如果你想要完全覆盖其所有的行为,你可以实现ErrorController并注册对应实现类的bean,你也可以通过定义ErrorAttributes类的bean,保留原来的机制,替换content(错误信息)。
你可以通过@ControllerAdvice来给指定的controller或exception类型。
@ControllerAdvice(basePackageClasses = FooController.class) public class FooControllerAdvice extends ResponseEntityExceptionHandler { @ExceptionHandler(YourException.class) @ResponseBody ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) { HttpStatus status = getStatus(request); return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status); } private HttpStatus getStatus(HttpServletRequest request) { Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); if (statusCode == null) { return HttpStatus.INTERNAL_SERVER_ERROR; } return HttpStatus.valueOf(statusCode); } }
在上面的例子中,如果一个在FooController在的包下的Controller抛出YourException,返回结果将由基于ErrorAttributes的结果表现变成基于CustomerErrorType的JSON字符串。
自定义错误页面
你可以在/error下定义错误页面。错误页面既不能为静态HTML(即在任何静态资源目录下)也不能为模板。文件名应该为错误代码值或错误代码匹配值。
例如,404错误
src/ +- main/ +- java/ | + <source code> +- resources/ +- public/ +- error/ | +- 404.html +- <other public assets>
5xx错误
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftl
+- <other templates>
你也可以通过实现ErrorViewResolver来配置你的错误信息
public class MyErrorViewResolver implements ErrorViewResolver { @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { // Use the request or status to optionally return a ModelAndView return ... } }
匹配SpringMvc外部的错误
对于不在SpringMvc内部的错误,你可以用ErrorPageRegistrar接口直接注册错误页面。该接口直接作用于嵌入的容器,因此即使你不创建DispatcherServlet它也能正常工作。
@Bean public ErrorPageRegistrar errorPageRegistrar(){ return new MyErrorPageRegistrar(); } // ... private static class MyErrorPageRegistrar implements ErrorPageRegistrar { @Override public void registerErrorPages(ErrorPageRegistry registry) { registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400")); } }
注:你注册的错误页面最终将被过滤器处理,过滤器会被注册为一个错误分发者(ERROR dispatcher)
@Bean public FilterRegistrationBean myFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new MyFilter()); ... registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class)); return registration; }
10、Spring HATEOAS
如果你正在编辑使用超媒体的RESTful API,Spring 为Spring HATEOAS提供自动配置,且能很好地与大部分应用工作。
使用@EnableHypermediaSupport注解可以使应用支持Spring HATEOAS。
11、支持CORS(跨域)
Spring 提供了对跨域的支持。
可以在Controller添加注解方式实现
@RestController @RequestMapping("/account") public class AccountController { @CrossOrigin @RequestMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }
也可以设置全局的
@Configuration public class MyConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**"); } }; } }