参考:https://docs.spring.io/spring-boot/docs/1.5.17.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications
翻译的官方文档,个人理解,仅供参考。
SpringBoot非常适合web应用程序的开发。可以使用Tomcat、Jetty或Undertow创建自包含的HTTP服务器。大部分应用程序会使用spring-boot-starter-web模块来快速开始。依赖如下:
org.springframework.boot
spring-boot-starter-web
1. SpringMVC的自动配置
SpringBoot为SpringMVC提供自动配置,对于大部分应用程序来说都能很好的运行。
自动配置在spring的默认配置上添加以下配置:
ContentNegotiatingViewResolver和BeanNameViewResolver
HttpMessageConverters
假如保留SpringBoot MVC的特点,并且只是想添加额外的MVC配置(如拦截器、转换器、控制器等),可以添加自定义的WebMvcConfigurerAdapter,通过@Configuration标识,而不需要@EnableWebMvc。
假如想要提供自定义的RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver
,可以声明一个WebMvcRegistrationsAdapter实例提供上述组件。
假如想要完全自定义SpringMVC,可以组合@Configuration和@EnableWebMvc。
2. HttpMessageConverters
SpringMVC使用HttpMessageConverters接口转换HTTP请求和响应。Object可以自动转换为JSON(使用Jackson)或XML(使用Jackson XML扩展或JAXB)开箱即用。String默认使用UTF-8编码。
如果需要添加自定义的转换器,可以使用SpringBoot提供的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);
}
}
任何在上下文中出现的HttpMessageConverter都会被添加进入转换器集合。可以通过这种方式覆盖默认的转换器。
3. 自定义JSON序列化和反序列化器
假如使用Jackson去序列化和反序列化JSON数据,你可能会自定义JsonSerializer
和JsonDeserializer
。自定义序列化器一般通过Jackson的一个模块,但是SpringBoot提供一个可供替代的@JsonComponent注解使之更加容易直接注册Spring Bean。
可以在JsonSerializer
或JsonDeserializer实现上直接添加
@JsonComponent注解。或者该注解放在一个普通Java类上,该类包含序列化或反序列化器的内部类。示例:
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 {
// ...
}
public static class Deserializer extends JsonDeserializer {
// ...
}
}
在上下文中的所有@JsonComponent注释的bean都会自动注册;因为该注解有@Component注解,所以通过组件扫描也可以注册为bean。
SpringBoot也提供 JsonObjectSerializer和JsonObjectDeserializer基类可以替代标准的Jackson的序列化器。
4. 静态资源
默认情况下,Spring Boot将从类路径中的/static(或/public、/resources、/META-INF/resources)目录或ServletContext的根目录中提供静态内容。使用了Spring MVC中的ResourceHttpRequestHandler,可以通过添加自己的WebMvcConfigurerAdapter并覆盖addResourceHandlers方法来修改该行为。
在独立的Web应用程序中,还启用了容器中的默认servlet充当后备,如果Spring决定不去处理它,则从ServletContext的根目录提供内容。 大多数情况下这不会发生(除非修改了默认的MVC配置),因为Spring总是能够通过DispatcherServlet处理请求。
默认情况下,资源通过/**映射,通过spring.mvc.static-path-pattern属性可以进行修改。
示例:修改为加上/resources
spring.mvc.static-path-pattern=/resources/**
还可以使用spring.resources.static-locations属性自定义静态资源位置(将替换默认的目录位置)。 如果执行此操作,默认的欢迎页面检测将切换到自定义位置。 因此,如果启动时在自定义的资源目录下有index.html,它将成为应用程序的主页。
除了上面的“标准”静态资源位置之外,还为Webjars内容制作了一个特例。 如果以Webjars格式打包,那么在/webjars/**中具有路径的任何资源都将从jar文件中提供。
提示:假如应用被打包为jar那就不要使用src/main/webapp目录。尽管该目录是一个标准的资源目录,但是它仅在打包为war时起作用;并且在打包为jar时,大部分构建工具会忽略该目录。
Spring Boot还支持Spring MVC提供的高级资源处理功能,允许使用缓存破坏静态资源或使用与Webjars无关的URL。
要为Webjars使用版本无关的URL,只需添加webjars-locator依赖项。 然后声明你的Webjar,以jQuery为例,作为“/webjars/jquery/dist/jquery.min.js”,结果为“/webjars/jquery/xyz/dist/jquery.min.js”,其中xyz是Webjar版本。
要使用缓存清除,以下配置将为所有静态资源配置缓存清除解决方案,有效地在URL中添加内容哈希,例如
配置如下:
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
提示:由于ResourceUrlEncodingFilter为Thymeleaf和FreeMarker自动配置,因此在运行时在模板中重写资源链接。 您应该在使用JSP时手动声明此过滤器。 目前不会自动支持其他模板引擎,但可以使用自定义模板宏/帮助程序以及ResourceUrlProvider的使用。
使用(例如)JavaScript模块加载器动态加载资源时,不能重命名文件。 这就是为什么其他策略也得到支持并可以合并的原因。 “固定”策略将在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 /”下的JavaScript模块将使用固定版本控制策略“/v12/js/lib/mymodule.js”,而其他资源仍将使用内容一个
查看ResourceProperties获取更多可选项。
5. 自定义Favicon
Spring Boot在配置的静态内容位置和类路径的根目录中(按此顺序)中查找favicon.ico。 如果存在此类文件,则会自动将其用作应用程序的favicon。
6. ConfigurableWebBindingInitializer
Spring MVC使用WebBindingInitializer为特定请求初始化WebDataBinder。 如果创建自定义的ConfigurableWebBindingInitializer @Bean,Spring Boot将自动配置Spring MVC以使用它。
7. 错误处理
SpringBoot默认提供一个/error映射处理所有错误,它被注册为servlet容器的全局错误页面。对于机器客户端来说,它将生成一个JSON响应,其中包含错误、HTTP状态和异常消息详细信息。对于浏览器客户端来说,有一个“whitelabel”错误视图,以HTML格式呈现相同的数据(要自定义它,只需添加一个解析为'error'的View)。彻底替换默认的表现形式,可以实现ErrorController并注册为bean,或者只是添加ErrorAttributes类型的bean以使用现有机制但替换内容。
提示:BasicErrorController
可以被用作实现自定义ErrorController的基类。如果要为新内容类型添加处理器,则此功能特别有用(默认情况下是专门处理text/html并为其他所有内容提供后备)。因此,只需要继承BasicErrorController并添加一个有produces
属性的@RequestMapping的public方法,并创建一个新类型的bean。
也可以定义一个@ControllerAdvice为一个特定的controller 和(或)异常类型去返回自定义JSON文档。
@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相同的包中定义的控制器抛出YourException,则将使用CustomErrorType POJO的json表示而不是ErrorAttributes。
7.2 自定义错误页面
如果要显示给定状态代码的自定义HTML错误页面,请将文件添加到/error文件夹。 错误页面可以是静态HTML(即添加到任何静态资源文件夹下)或使用模板构建。 文件名应该是确切的状态代码或系列掩码。
例如,去映射404到一个静态页面,目录结构应该像这样:
src/
+- main/
+- java/
| +
使用FreeMarker模板映射5xx错误,目录结构应该像这样:
src/
+- main/
+- java/
| +
对于更复杂的映射,你可以添加实现ErrorViewResolver接口的bean:
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map model) {
// Use the request or status to optionally return a ModelAndView
return ...
}
}
也可以使用常规的SpringMVC特性如@ExceptionHandler方法和@ControllerAdvice。ErrorController
会处理所有未被处理的异常。
7.3 映射SpringMVC外部的错误页面
对于不使用Spring MVC的应用程序,可以使用ErrorPageRegistrar接口直接注册ErrorPages。 这种抽象直接与底层的嵌入式servlet容器一起工作,即使没有Spring MVC 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"));
}
}
if you register an ErrorPage
with a path that will end up being handled by a Filter
(e.g. as is common with some non-Spring web frameworks, like Jersey and Wicket), then the Filter
has to be explicitly registered as an ERROR
dispatcher, e.g.
@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
...
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
(the default FilterRegistrationBean
does not include the ERROR
dispatcher type).
8. Spring HATEOAS
如果您正在开发一个使用超媒体的RESTful API,Spring Boot会为Spring HATEOAS提供自动配置,适用于大多数应用程序。 自动配置取代了使用@EnableHypermediaSupport的需要,并注册了许多bean,以便于构建基于超媒体的应用程序,包括LinkDiscoverers(用于客户端支持)和配置为正确编组响应到所需表示的ObjectMapper。 ObjectMapper将基于spring.jackson.*属性。或Jackson2ObjectMapperBuilder bean(如果存在)进行自定义。
可以使用@EnableHypermediaSupport控制Spring HATEOAS的配置。 请注意,这将禁用上述的ObjectMapper自定义描述。
9. 跨域的支持
跨域资源共享Cross-origin resouce sharing(CORS)是大多数浏览器实现的W3C规范,允许以灵活的方式指定授权何种类型的跨域请求,而不是使用一些不太安全且功能较弱的方法,如IFRAME或JSONP。
从4.2版本开始,Spring MVC支持开箱即用的CORS。 在Spring Boot应用程序中使用带有@CrossOrigin注解的控制器方法CORS配置不需要任何特定配置(参考controller method CORS configuration)。 可以通过使用自定义的addCorsMappings(CorsRegistry)方法注册WebMvcConfigurer bean来定义全局CORS配置:
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}