注:本系列教程花了三个星期的业余时间来翻译,虽然尽心尽力,但水平有限,难免有失误或表达不太好,请尽力地骂,骂完,可以打赏安慰我,我才有动力改。
源文档地址:https://docs.spring.io/spring-boot/docs/2.2.x/reference/html/spring-boot-features.html#boot-features

7. 开发Web应用程序

Springboot非常适合Web应用程序开发。您可以使用嵌入式Tomcat、Jetty、Undertow或Netty创建一个独立的HTTP服务器。大多数Web应用程序使用 spring-boot-starter-web模块快速启动和运行。您还可以选择使用spring-boot-starter-webflux模块来构建反应式Web应用程序。

如果您还没有开发一个SpringBootWeb应用程序,您可以按照“HelloWorld”来操作。入门部分中的示例。

7.1. Spring Web MVC框架

SpringWebMVC框架(通常简称为“SpringMVC”)是一个功能丰富的“模型-视图-控制器”Web框架。SpringMVC允许您创建特殊的@Controller或@RestController 来处理传入的HTTP请求。控制器中的方法通过使用@RequestMapping annotations映射到HTTP。

下面的代码显示了一个典型的@RestController ,它为JSON数据提供服务:

@RestController
@RequestMapping(value="/users")
public class MyRestController {

    @RequestMapping(value="/{user}", method=RequestMethod.GET)
    public User getUser(@PathVariable Long user) {
        // ...
    }

    @RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
    List<Customer> getUserCustomers(@PathVariable Long user) {
        // ...
    }

    @RequestMapping(value="/{user}", method=RequestMethod.DELETE)
    public User deleteUser(@PathVariable Long user) {
        // ...
    }

}

SpringMVC是核心Spring框架的一部分, 参考文档中提供了详细信息。在spring.io/guides上还提供了几个涵盖Spring MVC的入门引导。

7.1.1. SpringMVC 自动配置

SpringBoot为SpringMVC提供了自动配置,适用于大多数应用程序。

自动配置在Spring默认值的基础上添加了以下功能:

如果要保留Spring Boot MVC功能,并且要添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),可以添加自己的@Configuration类(类型为WebMvcConfigurer),但不添加@EnableWebMvc。如果要提供RequestMappingHandlerMapping, RequestMappingHandlerAdapter, 或 ExceptionHandlerExceptionResolver的自定义实例,可以声明WebMvcRegistrationsAdapter实例以提供此类组件。

如果要完全控制SpringMVC,可以添加自己的@Configuration,并用@EnableWebMvc注释。

7.1.2. HttpMessageConverters

SpringMVC使用 HttpMessageConverter接口来转换HTTP请求和响应。合理的默认值是开箱即用的。例如,对象可以自动转换为JSON(通过使用Jackson库)或XML(通过使用Jackson XML扩展名(如果可用),或者通过使用JAXB(如果Jackson XML扩展名不可用)。默认情况下,字符串以UTF-8编码。

如果需要添加或自定义转换器,可以使用Spring引导的HttpMessageConverters类,如下所示:

import org.springframework.boot.autoconfigure.http.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 bean都将添加到转换器列表中。您也可以用同样的方法重写默认转换器。

7.1.3. 自定义JSON序列化程序和反序列化程序

如果使用Jackson对JSON数据进行序列化和反序列化,则可能需要编写自己的 JsonSerializer 和 JsonDeserializer 。自定义序列化程序通常通过模块向Jackson注册,但Spring Boot提供了一个可选的@JsonComponent注释,使直接注册SpringBean更加容易。

您可以直接在 JsonSerializer 或 JsonDeserializer 实现上使用 @JsonComponent注释。您还可以在包含序列化程序/反序列化程序作为内部类的类上使用它,如下例所示:

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> {
        // ...
    }

}

ApplicationContext 中的所有 @JsonComponent bean都会自动注册到Jackson。因为 @JsonComponent 是用 @Component进行注释的,所以应用通常的组件扫描规则。

SpringBoot还提供了JsonObjectSerializerJsonObjectDeserializer 基类,它们在序列化对象时为标准的Jackson版本提供了有用的替代方案。有关详细信息,请参见javadoc中的JsonObjectSerializerJsonObjectDeserializer

7.1.4. MessageCodesResolver

SpringMVC有一种生成错误代码的策略,用于呈现绑定错误的错误消息:MessageCodesResolver。如果设置了spring.mvc.message-codes-resolver.format属性前缀PREFIX_ERROR_CODEPOSTFIX_ERROR_CODE,则spring boot将为您创建一个(请参见DefaultMessageCodesResolver.Format中的枚举)。

7.1.5. 静态内容

默认情况下,Springboot服务于类路径中名为/static (或/public/resources/META-INF/resources)的目录或ServletContext的根目录中的静态内容。它使用SpringMVC中的ResourceHttpRequestHandler,这样您就可以通过添加自己的 WebMvcConfigurer并重写addResourceHandlers方法来修改该行为

在一个独立的Web应用程序中,容器中的默认servlet也被启用并充当一个回退,如果spring决定不处理它,它将从 ServletContext的根目录提供内容。大多数情况下,不会发生这种情况(除非修改默认的MVC配置),因为Spring总是可以通过DispatcherServlet处理请求。

默认情况下,资源映射到/**,但您可以使用spring.mvc.static-path-pattern属性对其进行优化。例如,将所有资源重新分配到/resources/**可以实现如下操作:

spring.mvc.static-path-pattern=/resources/**

还可以使用spring.resources.static-locations属性(将默认值替换为目录位置列表)自定义静态资源位置。根servlet上下文路径 "/"也自动添加为位置。

除了前面提到的“标准”静态资源位置之外,还为Webjars content做了一个特殊的案例。如果jar文件以webjars格式打包,那么在/webjars/**中具有路径的任何资源都是从jar文件提供服务的。

如果应用程序打包为JAR,则不要使用src/main/webapp目录。虽然这个目录是一个通用的标准,但是它只适用于war打包,并且如果您生成一个jar,大多数构建工具都会悄悄地忽略它
SpringBoot还支持SpringMVC提供的高级资源处理功能,允许使用诸如缓存占用静态资源或为Webjar使用版本无关的URL等用例。

要对Webjars使用版本不可知的URL,请添加·webjars-locator-core·依赖项。然后声明你的webjar。以jquery为例,添加/webjars/jquery/jquery.min.js/webjars/jquery/x.y.z/jquery.min.js。其中x.y.z 是Webjar版本。

如果使用jboss,则需要声明·webjars-locator-core·依赖项,而不是·webjars-locator-core。否则,所有Webjar都将解析为404。
要使用缓存总线,以下配置为所有静态资源提供缓存总线解决方案,有效地在URL中添加内容哈希,例如<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

到资源的链接在运行时在模板中被重写,这要归功于为thymeleaf和freemaker自动配置的ResourceUrlEncodingFilter。在使用JSP时,应该手动声明这个过滤器。当前不自动支持其他模板引擎,但可以使用自定义模板macros/helpersResourceUrlProvider.
例如,当使用JavaScript模块加载程序动态加载资源时,重命名文件不是一个选项。这就是为什么其他策略也得到了支持并可以合并的原因。一个“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/"”下的javascript模块使用fixed版本策略(/v12/js/lib/mymodule.js),而其他资源仍使用content策略(<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>)。

有关更多支持的选项,请参阅ResourceProperties

reference documentation.
这个特性已经在一篇专门的blog
post
文章和SpringFramework的参考文档中进行了详细描述。

7.1.6. 欢迎页

Spring引导支持静态和模板化欢迎页面。它首先在配置的静态内容位置中查找index.html文件。如果找不到,它将查找index模板。如果找到任何一个,它将自动用作应用程序的欢迎页面。

7.1.7. 自定义图标

SpringBoot在配置的静态内容位置和类路径的根目录中查找favicon.ico (按此顺序)。如果存在这样的文件,它将自动用作应用程序的图标。

7.1.8. 路径匹配和内容协商

SpringMVC可以通过查看请求路径并将其与应用程序中定义的映射(例如,控制器方法上的 @GetMapping 注解)匹配,将传入的HTTP请求映射到处理程序。

Spring boot默认选择禁用后缀模式匹配,这意味着像GET /projects/spring-boot.json 这样的请求不会与@GetMapping("/projects/spring-boot")映射匹配。这被认为是SpringMVC应用程序的最佳实践。此功能在过去主要用于没有发送正确的“Accept”请求头的HTTP客户端;我们需要确保向客户端发送正确的内容类型。如今,内容协商更加可靠。

还有其他处理HTTP客户端的方法,它们不总是发送正确的“Accept”请求头。不使用使用后缀匹配,我们可以使用一个查询参数来确保像GET /projects/spring-boot?format=json这样的请求,映射到@GetMapping("/projects/spring-boot")

spring.mvc.contentnegotiation.favor-parameter=true

#我们可以更改参数名,默认为“format”。
#spring.mvc.contentnegotiation.parameter-name=myparam

#我们还可以通过以下方式注册其他文件extensions/media 类型:

spring.mvc.contentnegotiation.media-types.markdown=text/markdown
如果您理解这些警告,并且仍然希望应用程序使用后缀模式匹配,则需要以下配置:

spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-suffix-pattern=true
或者,不打开所有后缀模式,只支持注册的后缀模式更安全:

spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-registered-suffix-pattern=true

#You can also register additional file extensions/media types with:
#spring.mvc.contentnegotiation.media-types.adoc=text/asciidoc

7.1.9. ConfigurableWebBindingInitializer

SpringMVC使用WebBindingInitializer为特定请求初始化WebDataBinder 。如果您创建自己的ConfigurableWebBindingInitializer @Bean,那么SpringBoot会自动配置SpringMVC来使用它。

7.1.10. 模板引擎

除了RESTWeb服务,您还可以使用SpringMVC来提供动态HTML内容。SpringMVC支持各种模板技术,包括thymeleaf、freemaker和jsp。另外,许多其他模板化引擎包括它们自己的SpringMVC集成。

Spring Boot包括以下模板化引擎的自动配置支持:

如果可能,应避免使用JSP。在将它们与嵌入的servlet容器一起使用时,有已知的限制
当您使用其中一个具有默认配置的模板引擎时,您的模板将自动从src/main/resources/templates中获取。

根据应用程序的运行方式的不同,Intellij IDEA对类路径的加载顺序不同。在IDE中通过main方法运行应用程序会导致与使用Maven或Gradle或从其打包的JAR运行应用程序时不同的顺序。这可能导致Spring引导在类路径上找不到模板。如果有这个问题,可以在IDE中重新排序类路径,以将模块的类和资源放在第一位。或者,可以配置模板前缀来搜索类路径上的每个 templates目录,如下所示:classpath*:/templates/

7.1.11. 错误处理

默认情况下,Spring引导提供了一个/error 映射,它以合理的方式处理所有错误,并在servlet容器中注册为“global”全局错误页。对于客户机,它生成一个JSON响应,其中包含错误、HTTP状态和异常消息的详细信息。对于浏览器客户端,有一个以HTML格式呈现相同数据的“WhiteLabel”错误视图(若要自定义该视图,请添加一个解析为错误的视图)。要完全替换默认行为,可以实现ErrorController 并注册该类型为bean定义,或者添加一个类型为ErrorAttributes的bean以使用现有机制,但替换内容。

BasicErrorController可以用作自定义ErrorController的基类。如果要为新的内容类型添加处理程序(默认情况下是专门处理text/html,并为其他所有内容提供回退),这尤其有用。为此,请扩展BasicErrorController,添加一个带有@RequestMapping 且具有products属性的公共方法,并创建一个新类型的bean。
您还可以定义一个用@ControllerAdvice注释的类,以自定义JSON文档以返回特定的控制器和/或异常类型,如下例所示:

@ControllerAdvice(basePackageClasses = AcmeController.class)
public class AcmeControllerAdvice 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);
    }

}

在前面的示例中,如果您的异常是由与AcmeController在同一个包中定义的控制器引发的,那么将使用CustomErrorType POJO的JSON表示,而不是使用ErrorAttributes表示。

自定义错误页
如果要显示给定状态代码的自定义HTML错误页,可以将文件添加到 /error文件夹。错误页可以是静态HTML(也就是说,添加到任何静态资源文件夹下),也可以使用模板生成。文件名应该是准确的状态代码或序列掩码。

例如,要将 404 映射到静态HTML文件,文件夹结构如下:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

要使用FreeMarker模板映射所有5xx错误,文件夹结构如下:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.ftl
             +- <other templates>

对于更复杂的映射,还可以添加实现ErrorViewResolver接口的bean,如下例所示:

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功能,如@ExceptionHandler 方法和@ControllerAdvice。然后,ErrorController接收任何未处理的异常。

对于不使用SpringMVC的应用程序,可以使用ErrorPageRegistrar接口直接注册 ErrorPages。这个抽象直接与底层的嵌入式servlet容器一起工作,即使您没有SpringMVC 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"));
    }

}

如果用一个过滤器处理的路径注册一个 ErrorPage (与某些非Spring Web框架(如Jersey和Wicket)相同),那么该过滤器必须显式注册为ERROR调度程序,如下例所示:

@Bean
public FilterRegistrationBean myFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new MyFilter());
    ...
    registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
    return registration;
}

注意,默认的FilterRegistrationBean不包括错误调度程序类型。

警告:当部署到servlet容器时,Spring Boot使用其错误页过滤器将具有错误状态的请求转发到相应的错误页。只有在尚未提交响应的情况下,才能将请求转发到正确的错误页。默认情况下,WebSphere ApplicationServer8.0及更高版本在成功完成servlet的服务方法后才提交响应。您应该通过将com.ibm.ws.webcontainer.invokeFlushAfterService设置为 false来禁用此行为。

7.1.12. Spring HATEOAS

如果您开发了一个使用超媒体的RESTfulAPI,那么SpringBoot为Spring HATEOAS提供了自动配置,它可以很好地与大多数应用程序配合使用。自动配置取消使用@EnableHypermediaSupport,并注册了一些bean以方便构建基于超媒体的应用程序,包括一个LinkDiscoverers (用于客户端支持)和一个ObjectMapper (配置为正确地将响应封送到所需的表示中)。ObjectMapper是通过设置各种 spring.jackson.* 属性来定制的,或者,如果有的话,通过Jackson2ObjectMapperBuilder bean来定制。

您可以使用@EnableHypermediaSupport来控制Spring Hateoas的配置。请注意,这样做会禁用前面描述的ObjectMapper定义。

7.1.13. CORS支持

跨源资源共享(cors)是由大多数浏览器实现的W3C规范,它允许您以灵活的方式指定哪些跨域请求是经过授权的,而不是使用一些不太安全和功能较弱的方法,如iframe或jsonp。

从4.2版开始,SpringMVC 支持CORS。在Spring引导应用程序中使用带有@CrossOrigin注释的控制器方法CORS配置而不需要任何特定的配置。全局CORS配置可以通过使用自定义的addCorsMappings(CorsRegistry)方法注册WebMvcConfigurer Bean来定义,如下例所示:

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }
        };
    }
}

7.2. Spring WebFlux 框架

SpringWebFlux是SpringFramework5.0中引入的新的响应式Web框架。与SpringMVC不同,它不需要servlet API,完全异步且不阻塞,并且通过响应式项目实现 响应式流规范。

SpringWebFlux有两种风格:基于功能和注释。基于注释的模型非常接近SpringMVC模型,如下面的示例所示:

@RestController
@RequestMapping("/users")
public class MyRestController {

    @GetMapping("/{user}")
    public Mono<User> getUser(@PathVariable Long user) {
        // ...
    }

    @GetMapping("/{user}/customers")
    public Flux<Customer> getUserCustomers(@PathVariable Long user) {
        // ...
    }

    @DeleteMapping("/{user}")
    public Mono<User> deleteUser(@PathVariable Long user) {
        // ...
    }

}

“webflux.fn”是一个功能变量,它将路由配置与请求的实际处理分开,如下例所示:

@Configuration
public class RoutingConfiguration {

    @Bean
    public RouterFunction<ServerResponse> monoRouterFunction(UserHandler userHandler) {
        return route(GET("/{user}").and(accept(APPLICATION_JSON)), userHandler::getUser)
                .andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
                .andRoute(DELETE("/{user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
    }

}

@Component
public class UserHandler {

    public Mono<ServerResponse> getUser(ServerRequest request) {
        // ...
    }

    public Mono<ServerResponse> getUserCustomers(ServerRequest request) {
        // ...
    }

    public Mono<ServerResponse> deleteUser(ServerRequest request) {
        // ...
    }
}

WebFlux是Spring框架的一部分,其参考文档.中提供了详细信息。

您可以定义任意多个 RouterFunctionbean来模块化路由器的定义。如果需要应用优先级,可以对bean进行排序。
要开始,请将 spring-boot-starter-webflux模块添加到应用程序中。

在应用程序中同时添加 spring-boot-starter-web和 spring-boot-starter-webflux模块会导致SpringBootAuto配置SpringMVC,而不是WebFlux。之所以选择这种行为,是因为许多Spring开发人员将spring-boot-starter-webflux添加到他们的SpringMVC应用程序中,以使用响应式WebClient。您仍然可以通过将所选应用程序类型设置为SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)来强制执行您的选择。

7.2.1. Spring WebFlux自动配置

SpringBoot为SpringWebFlux提供了自动配置,它适用于大多数应用程序。

自动配置在Spring默认值的基础上添加了以下功能:

HttpMessageReaderHttpMessageWriter实例配置编解码器(本文档稍后介绍)。

对服务静态资源的支持,包括对Webjar的支持(本文档后面将介绍)。

如果希望保留Spring引导WebFlux功能,并且希望添加其他WebFlux配置,则可以添加自己的@Configuration类,类型为 WebFluxConfigurer,但不使用@EnableWebFlux

如果您想完全控制SpringWebFlux,可以添加自己的@Configuration,并用@EnableWebFlux注释。

7.2.2. 带有HttpMessageReaders和HttpMessageWriters的HTTP编解码器

SpringWebFlux使用HttpMessageReaderHttpMessageWriter接口来转换HTTP请求和响应。通过查看类路径中可用的库,可以使用 CodecConfigurer将它们配置为具有合理的默认值。

SpringBoot通过使用 CodecCustomizer实例应用进一步的自定义。例如,spring.jackson.*配置键应用于json编解码器。

如果需要添加或自定义编解码器,可以创建自定义CodecCustomizer组件,如下例所示:

import org.springframework.boot.web.codec.CodecCustomizer;

@Configuration
public class MyConfiguration {

    @Bean
    public CodecCustomizer myCodecCustomizer() {
        return codecConfigurer -> {
            // ...
        }
    }

}

您还可以利用SpringBoot的自定义JSON序列化程序和反序列化程序

7.2.3. 静态内容

默认情况下,SpringBoot服务于类路径中名为/static(或/public/resources/META-INF/resources)的目录中的静态内容。它使用SpringWebFlux中的ResourceWebHandler,这样您就可以通过添加自己的WebFluxConfigurer并重写addResourceHandlers 方法来修改该行为。

默认情况下,资源被映射到/**,但您可以通过设置spring.webflux.static-path-pattern属性来调整它。例如,将所有资源重新分配到/resources/**可以实现如下操作:

spring.webflux.static-path-pattern=/resources/**

还可以使用spring.resources.static-locations自定义静态资源位置。这样做会用目录位置列表替换默认值。如果这样做,默认欢迎页面检测将切换到自定义位置。因此,如果启动时在任何位置都有index.html,那么它就是应用程序的主页。

除了前面列出的“标准”静态资源位置之外,还为Webjars content做了一个特殊的案例。如果以webjars格式打包,则任何路径为/webjars/**的资源都是从jar文件提供服务的。

SpringWebFlux应用程序并不严格依赖于servlet API,因此它们不能作为war文件部署,也不使用src/main/webapp目录。

7.2.4. 模板引擎

除了RESTWeb服务,您还可以使用SpringWebFlux来提供动态HTML内容。SpringWebFlux支持各种模板技术,包括Thymeleaf、FreeMarker和Mustache。

Spring Boot包括以下模板化引擎的自动配置支持:

当您使用其中一个具有默认配置的模板引擎时,您的模板将自动从src/main/resources/templates中获取。

7.2.5. 错误处理

SpringBoot提供了一个WebExceptionHandler,它以合理的方式处理所有错误。它在WebFlux提供的处理程序之前被 处理,WebFlux被认为是最后一个处理程序。对于客户机,它生成一个JSON响应,其中包含错误、HTTP状态和异常消息的详细信息。对于浏览器客户机,有一个“WhiteLabel”错误处理程序以HTML格式呈现相同的数据。您还可以提供自己的HTML模板来显示错误(参见下一节)。

定制此特性的第一步通常涉及使用现有机制,但需要替换或扩充错误内容。为此,您可以添加一个类型为ErrorAttributes的bean。

要更改错误处理行为,可以实现ErrorWebExceptionHandler 并注册该类型的bean定义。由于WebExceptionHandler的级别很低,所以Spring Boot还提供了一个方便的AbstractErrorWebExceptionHandler,让您能够以WebFlux的功能方式处理错误,如下例所示:

public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

    // Define constructor here

    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {

        return RouterFunctions
                .route(aPredicate, aHandler)
                .andRoute(anotherPredicate, anotherHandler);
    }

}

对于更完整的定义,您还可以直接子类化DefaultErrorWebExceptionHandler并重写特定的方法。

自定义错误页
如果要显示给定状态代码的自定义HTML错误页,可以将文件添加到/error 文件夹。错误页可以是静态HTML(即,添加到任何静态资源文件夹下)或使用模板生成。文件名应该是准确的状态代码或序列掩码。

例如,要将404映射到静态HTML文件,文件夹结构如下:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

要使用mustache模板映射所有 5xx错误,文件夹结构如下:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.mustache
             +- <other templates>

7.2.6. Web过滤

SpringWebFlux提供了一个 WebFilter接口,可以实现它来过滤HTTP请求-响应交换。在应用程序上下文中找到的WebFilter bean将自动用于过滤每个连接。

过滤器的顺序很重要,它们通过可以实现Ordered ,或者@Order注释。Springboot自动配置可以为您配置Web过滤器。执行此操作时,将使用下表中显示的顺序:

Web Filter Order
MetricsWebFilter Ordered.HIGHEST_PRECEDENCE + 1
WebFilterChainProxy (Spring Security) -100
HttpTraceWebFilter Ordered.LOWEST_PRECEDENCE - 10