7. Developing Web Applications

SpringBoot 很适合开发 web程序。你可以使用内嵌的 HTTP server (tomcat、jetty、undertow、netty)来创建web程序。大多数的web程序使用 spring-boot-starter-web 模块来构建。你也可以使用 spring-boot-starter-webflux 来构建响应式 web 程序。

如果还没有开发过 SpringBoot web 程序,你可以使用 Hello World 示例尝试一下。

7.1 The Spring Web MVC Framework

Spring Web MVC Framework 通常简称为 Spring MVC,一个 模型-视图-控制器框架。Spring MVC 容许你在 HTTP 入口类的 bean 上(Controller层)添加 @Controller 和 @RestController 注解。通过 @RequestMapping 注解将具体的请求映射到具体的方法上。

下面的代码显示了一个典型的@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 getUserCustomers(@PathVariable Long user) {
        // ...
    }

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

}

Spring MVC 是 Spring Framework 核心框架的一部分,详细的信息请参考 reference documentation。也有一些其他的内容可以参考 spring.io/guides

7.1.1 Spring MVC Auto-configuration

SpringBoot 为 Spring MVC 提供了自动配置功能可用在大多数的应用程序中。

自动配置(Auto-configuration)会在 Spring 基础上添加以下特性:

  • 包含 of ContentNegotiatingViewResolver 和 BeanNameViewResolver beans.
  • Support for serving static resources(支持静态资源), including support for WebJars (covered later in this document 参考 7.1.5 章节内容)).
  • 自动注册 Converter, GenericConverter, and Formatter beans.
  • 支持 HttpMessageConverters (参考 7.1.2 章节).
  • 自动注册 MessageCodesResolver (参考 7.1.4 章节).
  • Static index.html support.
  • Custom Favicon support (参考 7.1.7章节).
  • 自动使用 of a ConfigurableWebBindingInitializer bean (参考 7.1.9 章节).

如果你想要保留 Spring MVC 的定制配置且想要进行更多的定制(拦截器,格式化程序,视图控制器和其他功能)。您可以添加自定义的类型为WebMvcConfigurer的@Configuration类,但不添加@EnableWebMvc。

如果你想提供自定义的实例RequestMappingHandlerMapping, RequestMappingHandlerAdapter,或ExceptionHandlerExceptionResolver,并且任然保留 SpringBoot MVC 的配置,你可以声明一个类型为 WebMvcRegistrations 的 bean 和用它来提供自定义这些组件的实例。

如果要完全控制Spring MVC,则可以添加用@EnableWebMvc注释的自己的@Configuration,或者按照@EnableWebMvc的Javadoc中的说明添加自己的@Configuration注释的DelegatingWebMvcConfiguration。

7.1.2 HttpMessageConverters

Spring MVC 使用 HttpMessageConverter 接口转换 HTTP请求信息和响应信息,默认使用此消息转换器。比如,对象可以自动转换为 JSON (使用 JACKSON 类库)或者 XML(by using the Jackson XML extension, if available, or by using JAXB if the Jackson XML extension is not available) 。默认编码是 UTF-8.

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

import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;

@Configuration(proxyBeanMethods = false)   
public class MyConfiguration {

    @Bean
    public HttpMessageConverters customConverters() {
        HttpMessageConverter additional = ...
        HttpMessageConverter another = ...
        return new HttpMessageConverters(additional, another);
    }

}

上下文中存在的所有HttpMessageConverter bean都将添加到转换器列表中。 您也可以用相同的方法覆盖默认转换器

7.1.3 Custom JSON Serializers and Deserializers

如果使用Jackson序列化和反序列化JSON数据,则可能要编写自己的JsonSerializer和JsonDeserializer类。自定义序列化程序通常是通过模块向Jackson进行注册的(registered with Jackson through a module),但是 SpringBoot 提供了一个注解 @JsonComponent 可以是注册变得更加容易。

您可以直接在JsonSerializer、JsonDeserializer或KeyDeserializer实现中使用@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 {
        // ...
    }

    public static class Deserializer extends JsonDeserializer {
        // ...
    }

}

在应用程序上下文环境中,所有带有 @JsonComponent 注解的 bean 都会自动注册到 Jackson 中。因为 @JsonComponent 注解中包含了 @Component 注解,并且符合组件的扫描规则。

Spring Boot还提供了JsonObjectSerializer和JsonObjectDeserializer基类,这些基类在序列化对象时为标准Jackson版本提供了有用的替代方法。See JsonObjectSerializer and JsonObjectDeserializer in the Javadoc for details

7.1.4 MessageCodesResolver

Spring MVC has a strategy for generating error codes for rendering error messages from binding errors: MessageCodesResolver. If you set the spring.mvc.message-codes-resolver-format property PREFIX_ERROR_CODE or POSTFIX_ERROR_CODE, Spring Boot creates one for you (see the enumeration in DefaultMessageCodesResolver.Format).

Spring MVC 有一种从错误消息生成错误代码的机制: MessageCodesResolver.你可以设置 spring.mvc.message-codes-resolver-format 的值为 PREFIX_ERROR_CODE 或者 POSTFIX_ERROR_CODE,see the enumeration in DefaultMessageCodesResolver.Format

7.1.5 Static Content

默认情况,SpringBoot 提供资源的路径是 /static (/public or /resources or /META-INF/resources) 在 classpath 中 或 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属性来自定义静态资源位置(用目录位置列表替换默认值)

除了前面提到的“标准”静态资源位置,还有一个针对 Webjars 内容的特例。任何在/webjars/**中有路径的资源都是从jar文件中提供的,如果它们是以webjars格式打包的。

如果您的应用程序打包为jar,请不要使用src/main/webapp目录。虽然这个目录是一个通用的标准,但是它只适用于 war 包,如果你生成一个jar,它会被大多数构建工具忽略。

7.1.6 Welcome Page

Spring Boot supports both static and templated welcome pages. It first looks for an index.html file in the configured static content locations. If one is not found, it then looks for an index template. If either is found, it is automatically used as the welcome page of the application.

Spring Boot支持静态和模板的欢迎页面。 它首先在配置的静态内容位置中查找index.html文件。 如果未找到,则寻找 index 模板。如果一个都没有找到,它将自动用作应用程序的欢迎页面。

7.1.7 Custom Favicon

与其他静态资源一样,Spring Boot在已配置的静态内容位置中查找favicon.ico。 如果存在这样的文件,它将自动用作应用程序的图标。

7.1.8 Path Maching and Content Negotiation

SpringMVC 能够映射下行的HTTP请求到具体的 Controller 方法上(for example, @GetMapping annotations on Controller methods)。

SpringBoot 默认禁用了后缀匹配模式,这就导致 "GET /projects/spring-boot.json" 请求不能映射到 to @GetMapping("/projects/spring-boot") 路径上。而这却是 Spring MVC application的最佳实践。该功能在过去主要用于没有发送正确的“接受”请求头的HTTP客户端,我们需要确保向客户端发送正确的内容类型。如今,内容协商更加可靠。

还有其他方法来处理不一致地发送正确的“接受”请求头的HTTP客户端。我们可以使用一个查询参数来确保像“GET /projects/spring-boot?format=json "将映射到@ GetMapping("/projects/spring-boot "):

spring.mvc.contentnegotiation.favor-parameter=true

#We can change the parameter name, which is "format" by default:
#spring.mvc.contentnegotiation.parameter-name=myparam

#We can also register additional file extensions/media types with:
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

Spring MVC uses a WebBindingInitializer to initialize a WebDataBinder for a particular request. If you create your own ConfigurableWebBindingInitializer @Bean, Spring Boot automatically configures Spring MVC to use it.

7.1.10 Template Engines

除了REST Web服务之外,您还可以使用Spring MVC来提供动态HTML内容。 Spring MVC支持各种模板技术,包括Thymeleaf,FreeMarker和JSP。 同样,许多其他模板引擎包括它们自己的Spring MVC集成。

Spring Boot includes auto-configuration support for the following templating engines:

  • FreeMarker
  • Groovy
  • Thymeleaf
  • Mustache

如果可能的话,尽量避免使用 JSP.当使用内嵌的 servlet 时有一些限制需要知道,参考 7.4.5 章节。

当你使用上述模板引擎的默认配置时,模板内容会从 src/main/resources/templates 路径加载。

Depending on how you run your application, IntelliJ IDEA orders the classpath differently. Running your application in the IDE from its main method results in a different ordering than when you run your application by using Maven or Gradle or from its packaged jar. This can cause Spring Boot to fail to find the templates on the classpath. If you have this problem, you can reorder the classpath in the IDE to place the module’s classes and resources first. Alternatively, you can configure the template prefix to search every templates directory on the classpath, as follows: classpath:/templates/.
大致意思:配置文件加载和程序运行的方式有关系,在 IDEA 中类路径(classpath)有所不同,如果遇到问题可以修改一个配置: classpath
:/templates/.

7.1.11 Error Handing

默认情况,SpringBoot 提供了一个 /error 映射路径来捕获所有的错误,并且它在整个 servlet 容器中全局有效。它为客户端以 JSON 格式提供详细的错误信息:HTTP status 和 错误消息。对于浏览器,它会返回一个空白的错误页面包括同样的错误数据。如果要自定义,你可以实现 ErrorController 类并进行注册或者添加一个 ErrorAttributes 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);
    }

}

In the preceding example, if YourException is thrown by a controller defined in the same package as AcmeController, a JSON representation of the CustomErrorType POJO is used instead of the ErrorAttributes representation.

7.1.11.1 Custom Error Pages

如果你要根据不同的状态码显示自定义的 HTML 错误页面,你可以添加页面到 /error 文件夹下面。错误的页面可以是静态的HTML 页面或者动态模板。文件的名称需要和状态码保持一致。

如下示例所示,映射 404 错误到 HTML 页面,你的目录结构如下所示:

src/
 +- main/
     +- java/
     |   + 
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- 

映射 5xx 的错误使用 FreeMarker 模板,你的目录结构如下所示:

src/
 +- main/
     +- java/
     |   + 
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.ftlh
             +- 

如果要实现高级的功能,可以实现 ErrorViewResolver 接口,如下所示:

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

}

您还可以使用Spring MVC功能,例如@ExceptionHandler方法和@ControllerAdvice 注解。 然后,用 ErrorController 捕获所有未处理的异常。

7.1.11.2 Mapping Error Pages outside of Spring MVC

如果不使用 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 ends up being handled by a Filter (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, as shown in the following example:

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

请注意,默认的FilterRegistrationBean不包含ERROR调度程序类型。

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

7.1.12 Spring HATEOAS

If you develop a RESTful API that makes use of hypermedia, Spring Boot provides auto-configuration for Spring HATEOAS that works well with most applications. The auto-configuration replaces the need to use @EnableHypermediaSupport and registers a number of beans to ease building hypermedia-based applications, including a LinkDiscoverers (for client side support) and an ObjectMapper configured to correctly marshal responses into the desired representation. The ObjectMapper is customized by setting the various spring.jackson.* properties or, if one exists, by a Jackson2ObjectMapperBuilder bean.

You can take control of Spring HATEOAS’s configuration by using @EnableHypermediaSupport. Note that doing so disables the ObjectMapper customization described earlier.

7.1.13 CORS Support

跨域资源共享(CORS)是大多数浏览器实施的W3C规范,可让您灵活地指定授权哪种类型的跨域请求。而不是使用一些安全性和功能不强的方法(例如IFRAME或JSONP)。

从 4.2 开始,Spring MVC支持 CORS在Spring Boot应用程序中使用带有@CrossOrigin批注的控制器方法CORS配置不需要任何特定的配置。全局跨域(Global CORS)配置可以注册一个 WebMvcConfigurer(CorsRegistry) 的bean且自定义 addCorsMappings 方法。

@Configuration(proxyBeanMethods = false)
public class MyConfiguration {

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

7.2 The Spring Webflux Framework

Spring Webflux 是 Spring Framework5.0 引进的新的响应式web框架,与 Spring MVC 有所不同,它不需要 Servlet API,支持 完全异步、非阻塞,and implements the Reactive Streams specification through the Reactor project.

Spring WebFlux有两种风格:功能性和基于注释的。基于注释的模式非常接近于Spring MVC模式,如下面的示例所示

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

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

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

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

}

WebFlux.fn 是函数变体,它将路由配置与请求的实际处理分离开来,如下面的示例所示:

@Configuration(proxyBeanMethods = false)
public class RoutingConfiguration {

    @Bean
    public RouterFunction 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 getUser(ServerRequest request) {
        // ...
    }

    public Mono getUserCustomers(ServerRequest request) {
        // ...
    }

    public Mono deleteUser(ServerRequest request) {
        // ...
    }
}

WebFlux是Spring框架的一部分,详细的信息可以在它的参考文档中找到。

您可以根据需要定义任意数量的RouterFunction bean,以对路由器的定义进行模块化。 如果需要应用优先级,可以对Bean进行排序。

首先,将spring-boot-starter-webflux模块添加到您的应用程序中。

Adding both spring-boot-starter-web and spring-boot-starter-webflux modules in your application results in Spring Boot auto-configuring Spring MVC, not WebFlux. This behavior has been chosen because many Spring developers add spring-boot-starter-webflux to their Spring MVC application to use the reactive WebClient. You can still enforce your choice by setting the chosen application type to SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE).
如果在程序中添加了 spring-boot-starter-web 和 spring-boot-starter-webflux 模块,springBoot 会自动注册 SpringMVC 而不是 webflux。This behavior has been chosen because many Spring developers add spring-boot-starter-webflux to their Spring MVC application to use the reactive WebClient。你可以通过下面代码进行强制设置:

SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE).

7.2.1 Spring WebFlux Auto-configuration

Spring Boot为Spring WebFlux提供了自动配置,可以很好地与大多数应用程序配合使用。

自动配置在Spring默认设置的基础上增加了以下特性

  • Configuring codecs for HttpMessageReader and HttpMessageWriter instances (described later in this document).
    为HttpMessageReader和HttpMessageWriter实例配置编解码器

  • Support for serving static resources, including support for WebJars (described later in this document).
    支持提供静态资源,包括对webjar的支持

如果要保留Spring Boot WebFlux功能,并且要添加其他WebFlux配置,则可以添加自己的类型为WebFluxConfigurer的@Configuration类,但不添加@EnableWebFlux。

如果要完全控制Spring WebFlux,则可以添加带有@EnableWebFlux注释的自己的@Configuration。

7.2.2 Http Codes with HTtpMessageReaders and HttpMessageWriters

Spring Webflux 使用 HttpMessageReader 和 HttpMessageWriter 接口来转换 HTTP请求和响应。They are configured with CodecConfigurer to have sensible defaults by looking at the libraries available in your classpath.

Spring Boot provides dedicated configuration properties for codecs, spring.codec.. It also applies further customization by using CodecCustomizer instances. For example, spring.jackson. configuration keys are applied to the Jackson codec.

Spring Boot为编解码器 spring.codec.* 提供了专用的配置属性。 它还通过使用 CodecCustomizer 实例应用进一步的自定义。 例如,将 spring.jackson.* 配置应用于 Jackson 编解码器。

If you need to add or customize codecs, you can create a custom CodecCustomizer component, as shown in the following example:

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

@Configuration(proxyBeanMethods = false)
public class MyConfiguration {

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

}

You can also leverage Boot’s custom JSON serializers and deserializers(参考 7.1.3 章节).

7.2.3 Static Content

默认,SpringBoot 的静态资源从 /static (or /public or resources or /META-INF/resources)in classpath.它使用来自Spring WebFlux的ResourceWebHandler,因此您可以通过添加自己的WebFluxConfigurer并覆盖addResourceHandlers方法来修改行为。

By default, resources are mapped on /, but you can tune that by setting the spring.webflux.static-path-pattern property. For instance, relocating all resources to /resources/ can be achieved as follows:

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

你可以使用 spring.resources.static-locations 属性来自定义静态资源的路径。如果自定义了路径,那欢迎页面的路径也会随着改变。因此,如果在启动时在您的任何位置都有index.html,那么它就是应用程序的主页。

除了前面列出的“标准”静态资源位置之外,Webjar内容也有特殊情况。 如果jar文件以Webjars格式打包,则从jar文件提供带有/ webjars / **路径的所有资源。

Spring WebFlux applications do not strictly depend on the Servlet API, so they cannot be deployed as war files and do not use the src/main/webapp directory.

7.2.4 Template Engines

除了REST web服务之外,您还可以使用Spring WebFlux来提供动态HTML内容。Spring WebFlux支持多种模板技术,包括Thymeleaf、FreeMarker和Mustache。

Spring Boot includes auto-configuration support for the following templating engines:

  • FreeMarker
  • Thymeleaf
  • Mustache

When you use one of these templating engines with the default configuration, your templates are picked up automatically from src/main/resources/templates

7.2.5 Error Handling

SpringBoot 提供了 WebExceptionHandler 在合适的途径来处理所有的错误。它在处理顺序中的位置紧接在WebFlux提供的处理程序之前,该处理程序被认为是最后一个。它为客户端以 JSON 格式提供详细的错误信息:HTTP status 和 错误消息。对于浏览器,它会返回一个空白的错误页面包括同样的错误数据。你可以自定义 HTML 模板来自定义错误信息的显示。

定制此功能的第一步通常涉及使用现有机制,但替换或增加错误内容。 为此,您可以添加类型为ErrorAttributes的bean。

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

public class CustomErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

    // Define constructor here

    @Override
    protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) {

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

}

For a more complete picture, you can also subclass DefaultErrorWebExceptionHandler directly and override specific methods.

7.2.5.1 Custom Error Pages

参考 7.1.11.1章节

7.2.6 Web Filters

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

如果过滤器的顺序很重要,则可以实现 Ordered 接口或使用@Order进行注解。Spring Boot自动配置可能会为您配置Web过滤器。 这样做时,将使用下表中显示的顺序:

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

7.3 JAX-RS and Jersey

If you prefer the JAX-RS programming model for REST endpoints, you can use one of the available implementations instead of Spring MVC. Jersey and Apache CXF work quite well out of the box. CXF requires you to register its Servlet or Filter as a @Bean in your application context. Jersey has some native Spring support, so we also provide auto-configuration support for it in Spring Boot, together with a starter.

7.4 Embedded Servlet Contaner Support

Spring Boot includes support for embedded Tomcat, Jetty, and Undertow servers. Most developers use the appropriate “Starter” to obtain a fully configured instance. By default, the embedded server listens for HTTP requests on port 8080.

7.4.1 Servlet,Filters,and listeners

当使用内嵌的 servlet 容器时,你可以注册 serlvet,filters,listerners ,可以使用Spring bean,也可以扫描Servlet组件。

Registering Servlets,Filters,and Listeners as Spring Beans

任何作为 Spring Bean 的 Servlet,Filter 或 Listener 实例都向嵌入式容器注册。如果要在配置过程中引用application.properties中的值,这可能特别方便。

默认情况下,如果上下文只包含一个Servlet,它将被映射到/。在多个servlet beans的情况下,bean名称用作路径前缀。过滤器映射到 /* 。

如果基于约定的映射不够灵活,则可以使用ServletRegistrationBean,FilterRegistrationBean和ServletListenerRegistrationBean类进行完全控制。

It is usually safe to leave Filter beans unordered. If a specific order is required, you should annotate the Filter with @Order or make it implement Ordered. You cannot configure the order of a Filter by annotating its bean method with @Order. If you cannot change the Filter class to add @Order or implement Ordered, you must define a FilterRegistrationBean for the Filter and set the registration bean’s order using the setOrder(int) method. Avoid configuring a Filter that reads the request body at Ordered.HIGHEST_PRECEDENCE, since it might go against the character encoding configuration of your application. If a Servlet filter wraps the request, it should be configured with an order that is less than or equal to OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER.

7.4.2 Servlet Context Initialization

嵌入式Servlet容器不会直接执行Servlet 3.0+ javax.servlet.ServletContainerInitializer接口或Spring的org.springframework.web.WebApplicationInitializer接口。 这是一个有意的设计决定,旨在降低旨在在战争中运行的第三方库可能破坏Spring Boot应用程序的风险。

如果需要在Spring Boot应用程序中执行servlet上下文初始化,则应该注册一个实现org.springframework.boot.web.servlet.ServletContextInitializer接口的bean。 单个onStartup方法提供对ServletContext的访问,并且在必要时可以轻松地用作现有WebApplicationInitializer的适配器。

Scanning for Servlet,Filters and listeners

使用嵌入式容器时,可以通过使用@ServletComponentScan启用自动注册带有@ WebServlet,@ WebFilter和@WebListener的类。

@ServletComponentScan在独立容器中无效,而是使用容器的内置发现机制。

7.4.3 The ServletWebServerApplicationContext

7.4.4 Customizing Embedded Servlet Containers

常用的 Servlet 配置可以使用 Spring Environment 属性配置,通常我们使用 application.properties 配置文件。

常用服务配置:

  • Network settings: Listen port for incoming HTTP requests (server.port), interface address to bind to server.address, and so on.
  • Session settings: Whether the session is persistent (server.servlet.session.persistent), session timeout (server.servlet.session.timeout), location of session data (server.servlet.session.store-dir), and session-cookie configuration (server.servlet.session.cookie.*).
  • Error management: Location of the error page (server.error.path) and so on.
  • SSL
  • HTTP compression

7.4.5 JSP Limitations

当你使用内置的 servlet 容器运行 springboot 程序时,在 jsp 的支持上会有以下限制:

  • 如果你使用 war 包,在 jetty 和 tomcat 下可以运行,它可以使用 jar -jar 启动或者部署到标准的容器中。当使用 jar 包时就不支持 JSP 了。
  • Undertow 不支持 JSP。
  • 自定义的 error.jsp 不能覆盖默认的错误视图页面( error handling - 7.1.11),自定义(Custom error pages)可以使用。

7.5 Embedded Reactive Server Support

Spring Boot includes support for the following embedded reactive web servers: Reactor Netty, Tomcat, Jetty, and Undertow. Most developers use the appropriate “Starter” to obtain a fully configured instance. By default, the embedded server listens for HTTP requests on port 8080.

7.6 Reactive Server Resources Configuration

当自动注册 Reactor Netty 或者 Jetty server 后,SpringBoot 会自动创建指定的bean来处理 HTTP 资源: ReactorResourceFactory 实例 和 JettyResourceFactory 实例。

默认情况下,这些资源还将与Reactor Netty和Jetty客户端共享,以实现最佳性能,具体如下:

  • the same technology is used for server and clent;
  • the client instance is built using the WebClient.Builder bean auto-configured by Spring Boot

Developers can override the resource configuration for Jetty and Reactor Netty by providing a custom ReactorResourceFactory or JettyResourceFactory bean - this will be applied to both clients and servers.

You can learn more about the resource configuration on the client side in the WebClient Runtime section.

你可能感兴趣的:(7. Developing Web Applications)