spring boot就是一个大框架里面包含了许许多多的东西,其中spring就是最核心的内容之一,当然就包含spring mvc。spring mvc 是只是spring 处理web层请求的一个模块。因此他们的关系大概就是这样:spring mvc < spring Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 aop ,解决了面向横切面的编程,然后在此两者的基础上实现了其他延伸产品的高级功能。 Spring MVC是基于 Servlet 的一个 MVC 框架 主要解决 WEB 开发的问题,因为 Spring 的配置非常复杂,各种XML、 JavaConfig、hin处理起来比较繁琐。 于是为了简化开发者的使用,从而创造性地推出了Spring boot,约定优于配置,简化了spring的配置流程。 说得更简便一些:Spring 最初利用“工厂模式”(DI)和“代理模式”(AOP)解耦应用组件。 大家觉得挺好用,于是按照这种模式搞了一个 MVC框架(一些用Spring 解耦的组件),用开发 web 应用( SpringMVC )。 然后有发现每次开发都写很多样板代码,为了简化工作流程,于是开发出了一些“懒人整合包”(starter),这套就是 Spring Boot。 Spring MVC的功能Spring MVC提供了一种轻度耦合的方式来开发web应用。Spring MVC是Spring的一个模块,式一个web框架。 通过Dispatcher Servlet, ModelAndView 和 View Resolver,开发web应用变得很容易。解决的问题领域是网站应用程序或者服务开发——URL路由、Session、模板引擎、静态Web资源等等。 Spring Boot的功能Spring Boot实现了自动配置,降低了项目搭建的复杂度。 众所周知Spring框架需要进行大量的配置,Spring Boot引入自动配置的概念,让项目设置变得很容易。 Spring Boot本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于Spring框架的应用程序。也就是说,它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。 同时它集成了大量常用的第三方库配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot应用中这些第三方库几乎可以零配置的开箱即用(out-of-the-box),大部分的Spring Boot应用都只需要非常少量的配置代码,开发者能够更加专注于业务逻辑。Spring Boot只是承载者,辅助你简化项目搭建过程的。如果承载的是WEB项目,使用Spring MVC作为MVC框架,那么工作流程和你上面描述的是完全一样的,因为这部分工作是Spring MVC做的而不是Spring Boot。对使用者来说,换用Spring Boot以后,项目初始化方法变了,配置文件变了,另外就是不需要单独安装Tomcat这类容器服务器了,maven打出jar包直接跑起来就是个网站,但你最核心的业务逻辑实现与业务流程实现没有任何变化。 所以,用最简练的语言概括就是: Spring 是一个“引擎”; Spring MVC 是基于Spring的一个 MVC 框架 ; Spring Boot 是基于Spring4的条件注册的一套快速开发整合包。 引入ContentNegotiatingViewResolver和BeanNameViewResolver beans。 对静态资源的支持,包括对WebJars的支持。 自动注册Converter,GenericConverter,Formatter beans。 对HttpMessageConverters的支持。 自动注册MessageCodeResolver。 对静态index.html的支持。 对自定义Favicon的支持。 自动使用ConfigurableWebBindingInitializer bean。 Spring Boot支持静态和模板欢迎页面。它首先index.html在配置的静态内容位置中查找 文件。如果找不到,则会查找index模板。如果找到任何一个,它将自动用作应用程序的欢迎页面。、 Spring Boot favicon.ico在配置的静态内容位置和类路径的根目录(按此顺序)中查找a 。如果存在这样的文件,它会自动用作应用程序的图标。 Spring MVC可以通过查看请求路径并将它匹配到应用程序中定义的映射(例如@GetMapping Controller方法上的注释),将传入的HTTP请求映射到处理程序。 Spring Boot选择默认禁用后缀模式匹配,这意味着请求"GET /projects/spring-boot.json"不会匹配 @GetMapping("/projects/spring-boot")映射。这被认为是Spring MVC应用程序的 最佳实践。此功能在过去对于没有发送正确的“Accept”请求标头的HTTP客户端来说非常有用; 我们需要确保将正确的内容类型发送到客户端。如今,内容协商更可靠。 还有其他一些方法可以处理不一致地发送适当的“接受”请求标头的HTTP客户端。我们可以使用查询参数来确保类似的请求"GET /projects/spring-boot?format=json" 将映射到@GetMapping("/projects/spring-boot")以下内容,而不是使用后缀匹配: 如果您了解注意事项并仍然希望应用程序使用后缀模式匹配,则需要进行以下配置: FreeMarker Groovy Thymeleaf Velocity(1.4已不再支持) Mustache Spring Boot默认提供一个/error映射用来以合适的方式处理所有的错误,并将它注册为servlet容器中全局的 错误页面。对于机器客户端(相对于浏览器而言,浏览器偏重于人的行为),它会产生一个具有详细错误,HTTP状态,异常信息的JSON响应。对于浏览器客户端,它会产生一个白色标签样式(whitelabel)的错误视图,该视图将以HTML格式显示同样的数据(可以添加一个解析为'error'的View来自定义它)。为了完全替换默认的行为,你可以实现ErrorController,并注册一个该类型的bean定义,或简单地添加一个ErrorAttributes类型的bean以使用现存的机制,只是替换显示的内容。 注BasicErrorController可以作为自定义ErrorController的基类,如果你想添加对新context type的处理(默认处理text/html),这会很有帮助。你只需要继承BasicErrorController,添加一个public方法,并注解带有produces属性的@RequestMapping,然后创建该新类型的bean。 你也可以定义一个@ControllerAdvice去自定义某个特殊controller或exception类型的JSON文档: 在以上示例中,如果跟FooController相同package的某个controller抛出YourException,一个CustomerErrorType类型的POJO的json展示将代替ErrorAttributes展示。 自定义错误页面 如果想为某个给定的状态码展示一个自定义的HTML错误页面,你需要将文件添加到/error文件夹下。错误页面既可以是静态HTML(比如,任何静态资源文件夹下添加的),也可以是使用模板构建的,文件名必须是明确的状态码或一系列标签。 例如,映射404到一个静态HTML文件,你的目录结构可能如下: 使用FreeMarker模板映射所有5xx错误,你需要如下的目录结构: 对于更复杂的映射,你可以添加实现ErrorViewResolver接口的beans: 你也可以使用Spring MVC特性,比如@ExceptionHandler方法和@ControllerAdvice,ErrorController将处理所有未处理的异常。 映射Spring MVC以外的错误页面 对于不使用Spring MVC的应用,你可以通过ErrorPageRegistrar接口直接注册ErrorPages。该抽象直接工作于底层内嵌servlet容器,即使你没有Spring MVC的DispatcherServlet,它们仍旧可以工作。 注.如果你注册一个ErrorPage,该页面需要被一个Filter处理(在一些非Spring web框架中很常见,比如Jersey,Wicket),那么该Filter需要明确注册为一个ERROR分发器(dispatcher),例如: (默认的FilterRegistrationBean不包含ERROR dispatcher类型)。 WebSphere应用服务器的错误处理 当部署到一个servlet容器时,Spring Boot通过它的错误页面过滤器将带有错误状态的请求转发到恰当的错误页面。request只有在response还没提交时才能转发(forwarded)到正确的错误页面,而WebSphere应用服务器8.0及后续版本默认情况会在servlet方法成功执行后提交response,你需要设置com.ibm.ws.webcontainer.invokeFlushAfterService属性为false来关闭该行为。 本文相关视频连接理清SpringBoot与SpringMVC的关系
Spring MVC自动配置
HttpMessageConverters
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);
}
}
自定义JSON序列化器和反序列化器
MessageCodesResolver
静态内容
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
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
欢迎页面
自定义Favicon
路径匹配和内容协商
spring.mvc.contentnegotiation.favor-parameter = true
#我们可以更改参数名称,默认为“格式”:
#spring.mvc.contentnegotiation.parameter-name = myparam
#我们还可以通过以下方式注册其他文件扩展名/媒体类型:
spring.mvc.contentnegotiation.media-types.markdown = text / markdown
spring.mvc.contentnegotiation.favor-path-extension = true
#您也可以将该功能限制为已知扩展
#spring.mvc.pathmatch.use-registered-suffix-pattern = true
#我们还可以通过以下方式注册其他文件扩展名/媒体类型:
#spring.mvc.contentnegotiation.media-types.adoc = text / asciidoc
ConfigurableWebBindingInitializer
模板引擎
错误处理
@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);
}
}
src/
+- main/
+- java/
| +
src/
+- main/
+- java/
| +
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map
@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"));
}
}
@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
...
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
Spring HATEOAS
CORS支持
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}