20191128 Spring Boot官方文档学习(9.4-9.8)

9.4。Spring MVC

Spring Boot有许多启动器包含Spring MVC。请注意,一些启动器包括对Spring MVC的依赖,而不是直接包含它。

9.4.1。编写JSON REST服务

只要Jackson2在类路径上,Spring Boot应用程序中的任何Spring @RestController默认情况下都应呈现JSON响应,如以下示例所示:

@RestController
public class MyController {

    @RequestMapping("/thing")
    public MyThing thing() {
            return new MyThing();
    }

}

只要MyThing可以由Jackson2序列化(对于普通的POJO或Groovy对象为true),则localhost:8080/thing默认情况下会为其提供JSON表示。请注意,在浏览器中,有时可能会看到XML响应,因为浏览器倾向于发送XML的接受标头。

9.4.2。编写XML REST服务

如果类路径上具有Jackson XML扩展(jackson-dataformat-xml),则可以使用它来呈现XML响应。我们用于JSON的先前示例可以正常工作。要使用Jackson XML渲染器,请将以下依赖项添加到您的项目中:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

如果无法使用Jackson的XML扩展而可以使用JAXB,则可以将MyThing注释为@XmlRootElement,如以下示例所示:

@XmlRootElement
public class MyThing {
    private String name;
    // .. getters and setters
}

JAXB仅在Java 8中是开箱即用的。如果您使用的是较新的Java版本,请在项目中添加以下依赖项:

<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
</dependency>

要使服务器呈现XML而不是JSON,您可能必须发送Accept: text/xml标头(或使用浏览器)。

9.4.3。自定义Jackson ObjectMapper

Spring MVC(客户端和服务器端)使用HttpMessageConverters来协商HTTP交换中的内容转换。如果Jackson在类路径中,则您已经获得Jackson2ObjectMapperBuilder所提供的默认转换器,该转换器的实例已为您自动配置。

ObjectMapper(或Jackson XML转换器XmlMapper)实例(默认创建)具有以下定义的属性:

  • MapperFeature.DEFAULT_VIEW_INCLUSION 被禁用
  • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 被禁用
  • SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 被禁用

Spring Boot还具有一些功能,可以更轻松地自定义此行为。

您可以使用Environment配置ObjectMapperXmlMapper实例。Jackson提供了一套广泛的简单的开/关功能,可用于配置其处理的各个方面。在六个枚举(在Jackson中)中描述了这些功能,这些枚举映射到环境中的属性:

Enum 属性 值域
com.fasterxml.jackson.databind.DeserializationFeature spring.jackson.deserialization.<feature_name> true,false
com.fasterxml.jackson.core.JsonGenerator.Feature spring.jackson.generator.<feature_name> true,false
com.fasterxml.jackson.databind.MapperFeature spring.jackson.mapper.<feature_name> true,false
com.fasterxml.jackson.core.JsonParser.Feature spring.jackson.parser.<feature_name> true,false
com.fasterxml.jackson.databind.SerializationFeature spring.jackson.serialization.<feature_name> true,false
com.fasterxml.jackson.annotation.JsonInclude.Include spring.jackson.default-property-inclusion always,non_null,non_absent,non_default,non_empty

例如,要启用漂亮打印,请设置spring.jackson.serialization.indent_output=true。请注意,由于使用了宽松绑定,indent_output的大小写不必与相应的枚举常量INDENT_OUTPUT的大小写匹配。

这种基于Environment的配置适用于自动配置的Jackson2ObjectMapperBuilder Bean,并且适用于使用构建器创建的任何映射器,包括自动配置的ObjectMapper Bean。

上下文中的Jackson2ObjectMapperBuilder可以由一个或多个Jackson2ObjectMapperBuilderCustomizer bean 自定义。可以对此类定制器beans进行排序(SpringBoot自己的定制器的顺序为0),从而可以在SpringBoot定制之前和之后应用其他定制。

任何类型的com.fasterxml.jackson.databind.Module bean都会自动向自动配置的Jackson2ObjectMapperBuilder中注册,并应用于它创建的任何ObjectMapper实例。当您向应用程序中添加新功能时,这提供了一种用于贡献自定义模块的全局机制。

如果要ObjectMapper完全替换默认值,请定义该类型的@Bean并将其标记为@Primary,或者,如果您更喜欢基于构建器的方法,请定义一个Jackson2ObjectMapperBuilder @Bean。请注意,无论哪种情况,这样做都会禁用ObjectMapper的所有自动配置。

如果提供任何MappingJackson2HttpMessageConverter类型的@Bean,它们将替换MVC配置中的默认值。另外,还提供了一种HttpMessageConverters类型的便捷bean (如果使用默认的MVC配置,该bean 始终可用)。它提供了一些有用的方法来访问默认的和用户增强的消息转换器。

有关更多详细信息,请参见WebMvcAutoConfiguration源代码。

源码学习:

org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration

org.springframework.boot.autoconfigure.jackson.JacksonProperties

9.4.4。自定义@ResponseBody渲染

Spring使用HttpMessageConverters渲染@ResponseBody(或@RestController的响应)。您可以通过在Spring Boot上下文中添加适当类型的bean来贡献额外的转换器。如果您添加的bean的类型无论如何都是默认包含的(例如用于JSON转换的MappingJackson2HttpMessageConverter),它将替换默认值。如果您使用默认的MVC配置,HttpMessageConverters类型的便捷bean将始终可用。它提供了一些有用的方法来访问默认的和用户增强的消息转换器(例如,如果您想将它们手动注入到custom RestTemplate中,可能会很有用)。

与正常的MVC用法一样,您提供的任何WebMvcConfigurer bean也可以通过重写configureMessageConverters方法来贡献转换器。但是,与普通的MVC不同,您只能提供所需的其他转换器(因为Spring Boot使用相同的机制来提供其默认值)。最后,如果您通过提供自己的@EnableWebMvc配置来退出Spring Boot默认MVC 配置,则可以使用WebMvcConfigurationSupportgetMessageConverters方法完全控制并手动完成所有操作。

请参阅WebMvcAutoConfiguration源代码以获取更多详细信息。

9.4.5。处理分段文件上传

Spring Boot包含Servlet 3 的 javax.servlet.http.Part API以支持上传文件。默认情况下,Spring Boot将Spring MVC配置为单个请求中每个文件最大大小为1MB,最大文件数据为10MB。您可以覆盖这些值,使用MultipartProperties类公开的属性覆盖中间数据的存储位置(例如,存储到/tmp目录)以及将数据刷新到磁盘的阈值。例如,如果您要指定文件不受限制,请将spring.servlet.multipart.max-file-size属性设置为-1。

当您想在Spring MVC控制器处理程序方法中将多部分编码的文件数据作为带@RequestParam注释的MultipartFile类型的参数来接收时,多部分支持会很有帮助。

有关MultipartAutoConfiguration更多详细信息,请参见源码。

建议使用容器的内置支持进行分段上传,而不要引入其他依赖项,例如Apache Commons File Upload。

9.4.6。关闭Spring MVC DispatcherServlet

默认情况下,所有内容均从应用程序的根目录(/)提供。如果您希望映射到其他路径,则可以如下配置:

spring.mvc.servlet.path=/acme

如果您有其他servlet,则可以声明一个类型为Servlet或ServletRegistrationBean的@Bean,然后Spring Boot会将它们透明地注册到容器。由于Servlet是通过这种方式注册的,因此可以将它们映射到DispatcherServlet的子上下文而无需调用它。

配置您自己的DispatcherServlet是不寻常的,但是如果您确实需要这样做,则还必须提供一个 DispatcherServletPath类型的@Bean来提供自定义DispatcherServlet的路径。

9.4.7。关闭默认的MVC配置

完全控制MVC配置的最简单方法是为您自己的@Configuration提供@EnableWebMvc注释。这样做会使您掌握所有MVC配置。

9.4.8。自定义ViewResolvers

ViewResolver是Spring MVC的核心组件,将@Controller中的视图名称转换为实际的View实现。请注意,ViewResolvers主要用于UI应用程序,而不是REST风格的服务(View不用于呈现@ResponseBody)。有很多ViewResolver实现可供选择,Spring本身对是否应使用哪个没有意见。另一方面,Spring Boot根据在类路径和应用程序上下文中找到的内容为您安装一个或两个。DispatcherServlet会使用它在应用程序上下文中找到的所有解析器,依次尝试每个解析器,直到获得结果为止。如果添加自己的解析器,则必须知道其顺序以及解析器的添加位置。

WebMvcAutoConfiguration将以下ViewResolvers添加到您的上下文中:

  • 一个名为defaultViewResolverInternalResourceViewResolver。此Resolver查找可以通过使用DefaultServlet渲染的物理资源(包括静态资源和JSP页面,如果使用的话)。它将一个前缀和一个后缀应用于视图名称,然后在Servlet上下文中查找具有该路径的物理资源(默认值均为空,但可以通过spring.mvc.view.prefixspring.mvc.view.suffix进行外部配置访问)。您可以通过提供相同类型的bean覆盖它。
  • 一个名为beanNameViewResolverBeanNameViewResolver。这是视图解析器链的有用成员,可以拾取与被解析View名称相同的所有bean 。不必重写或替换它。
  • 仅当实际存在类型为View的 bean的情况下,才添加一个名为viewResolverContentNegotiatingViewResolver。这是一个“主”解析器,委派给所有其他解析器,并尝试查找与客户端发送的“Accept” HTTP标头匹配的内容。您可以通过定义一个名为viewResolverContentNegotiatingViewResolver bean 来关闭自动配置。
  • 如果您使用Thymeleaf,则还有一个名为thymeleafViewResolverThymeleafViewResolver。它通过在视图名称前后加上前缀和后缀来查找资源。前缀为spring.thymeleaf.prefix,后缀为spring.thymeleaf.suffix。前缀和后缀的值分别默认为classpath/templates/.html。您可以通过提供相同名称的bean 来覆盖ThymeleafViewResolver
  • 如果您使用FreeMarker,则还有一个名为freeMarkerViewResolverFreeMarkerViewResolver。它通过在视图名称前加上前缀和后缀来在加载程序路径spring.freemarker.templateLoaderPath(已外部化并具有默认值classpath:/templates/)中查找资源。前缀被外部化为spring.freemarker.prefix,后缀被外部化为spring.freemarker.suffix。前缀和后缀的默认值分别为空和.ftlh。您可以通过提供相同名称的bean 来覆盖FreeMarkerViewResolver
  • 如果您使用Groovy模板(实际上,如果groovy-templates在类路径中),则还具有一个名为groovyMarkupViewResolverGroovyMarkupViewResolver。它通过在视图名称周围加上前缀和后缀(并扩展为spring.groovy.template.prefixspring.groovy.template.suffix)来在加载器路径中查找资源。前缀和后缀分别具有默认值classpath:/templates/.tpl。您可以通过提供相同名称的bean 来覆盖GroovyMarkupViewResolver
  • 如果您使用Mustache,那么您还将有一个名为mustacheViewResolverMustacheViewResolver。它通过在视图名称前后加上前缀和后缀来查找资源。前缀为spring.mustache.prefix,后缀为spring.mustache.suffix。前缀和后缀的值分别默认为classpath:/templates/.mustache。您可以通过提供相同名称的bean 来覆盖MustacheViewResolver

有关更多详细信息,请参见以下部分:

  • WebMvcAutoConfiguration
  • ThymeleafAutoConfiguration
  • FreeMarkerAutoConfiguration
  • GroovyTemplateAutoConfiguration

9.5。使用Spring Security进行测试

Spring Security提供了对以特定用户身份运行测试的支持。例如,下面的代码段中的测试将与具有ADMIN角色的经过身份验证的用户一起运行。

@Test
@WithMockUser(roles="ADMIN")
public void requestProtectedUrlWithUser() throws Exception {
    mvc
        .perform(get("/"))
        ...
}

Spring Security提供了与Spring MVC Test的全面集成,并且在使用@WebMvcTest slice和MockMvc进行测试控制器时也可以使用它。

有关Spring Security的测试支持的更多详细信息,请参阅Spring Security的参考文档

9.6。Jersey

9.6.1。使用Spring Security保护Jersey端点

可以使用Spring Security来保护基于Jersey的Web应用程序,其方式与用来保护基于Spring MVC的Web应用程序的方式几乎相同。但是,如果您想在Jersey上使用Spring Security的方法级安全性,则必须将Jersey配置为使用setStatus(int)而不是sendError(int)。这可以防止Jersey在Spring Security有机会向客户端报告身份验证或授权失败之前提交响应。

jersey.config.server.response.setStatusOverSendError属性必须在应用程序的ResourceConfig Bean 上设置为true,如以下示例所示:

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(Endpoint.class);
        setProperties(Collections.singletonMap("jersey.config.server.response.setStatusOverSendError", true));
    }

}

9.7。HTTP客户端

Spring Boot提供了许多可与HTTP客户端一起使用的启动器。本节回答与使用它们有关的问题。

9.7.1。配置RestTemplate使用代理

RestTemplate自定义中所述,您可以使用带RestTemplateCustomizerRestTemplateBuilder来构建自定义RestTemplate。这是创建RestTemplate配置为使用代理的推荐方法。

代理配置的确切详细信息取决于所使用的基础客户端请求工厂。以下示例使用HttpClient进行配置HttpComponentsClientRequestFactory,该HttpClient代理除192.168.0.5以下主机之外的所有主机:

static class ProxyCustomizer implements RestTemplateCustomizer {

    @Override
    public void customize(RestTemplate restTemplate) {
        HttpHost proxy = new HttpHost("proxy.example.com");
        HttpClient httpClient = HttpClientBuilder.create().setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {

            @Override
            public HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context)
                    throws HttpException {
                if (target.getHostName().equals("192.168.0.5")) {
                    return null;
                }
                return super.determineProxy(target, request, context);
            }

        }).build();
        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
    }

}

9.7.2。配置基于Reactor Netty的WebClient使用的TcpClient

Reactor Netty在类路径上时,将自动配置基于Reactor Netty的WebClient。要自定义客户端对网络连接的处理,请提供一个ClientHttpConnector bean。以下示例配置60秒的连接超时并添加ReadTimeoutHandler

@Bean
ClientHttpConnector clientHttpConnector(ReactorResourceFactory resourceFactory) {
    TcpClient tcpClient = TcpClient.create(resourceFactory.getConnectionProvider())
            .runOn(resourceFactory.getLoopResources()).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 60000)
            .doOnConnected((connection) -> connection.addHandlerLast(new ReadTimeoutHandler(60)));
    return new ReactorClientHttpConnector(HttpClient.from(tcpClient));
}

请注意ReactorResourceFactory对连接提供程序和事件循环资源的使用。这确保了用于服务器接收请求和客户端发出请求的资源的有效共享。

9.8。日志记录

除了通常由Spring Framework的spring-jcl模块提供的Commons Logging API之外,Spring Boot没有强制性的日志记录依赖项。要使用Logback,您需要将其包括spring-jcl在类路径中。最简单的方法是通过启动器,这都取决于spring-boot-starter-logging。对于Web应用程序,您仅需要spring-boot-starter-web,因为它暂时依赖于日志记录启动器。如果使用Maven,则以下依赖项会为您添加日志记录:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Spring Boot有一个LoggingSystem抽象,它试图根据类路径的内容来配置日志记录。如果Logback可用,则它是首选。

如果您需要对日志记录进行的唯一更改是设置各种记录器的级别,则可以在application.properties里使用logging.level前缀来进行设置,如以下示例所示:

logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

您还可以使用logging.file.name来设置要写入日志的文件的位置(除了控制台)。

要配置日志记录系统的更细粒度的设置,您需要使用LoggingSystem所支持的本机配置格式。默认情况下,Spring Boot从系统的默认位置(例如Logback的classpath:logback.xml)拾取本地配置,但是您可以使用logging.config属性设置配置文件的位置。

9.8.1。配置Logback以进行日志记录

如果您需要将自定义设置超出application.properties可以设置的范围,则需要添加标准的Logback配置文件。您可以将logback.xml文件添加到类路径的根目录中,以供Logback查找。如果您想使用Spring Boot Logback扩展,也可以使用logback-spring.xml

Logback文档有一个专用部分,其中详细介绍了配置。

Spring Boot提供了许多可以包含在您自己配置中的logback 配置。这些includes旨在允许重新应用某些常见的Spring Boot约定。

org/springframework/boot/logging/logback/ 下提供了以下文件:

  • defaults.xml -提供转换规则,模式属性和通用记录器配置。
  • console-appender.xml - 使用CONSOLE_LOG_PATTERN添加了一个ConsoleAppender
  • file-appender.xml - 使用通过适当的设置的FILE_LOG_PATTERNROLLING_FILE_NAME_PATTERN添加了一个RollingFileAppender

此外,还提供了一个过时的 base.xml 文件以与早期版本的Spring Boot兼容。

一个典型的自定义logback.xml文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
    <logger name="org.springframework.web" level="DEBUG"/>
</configuration>

您的Logback配置文件也可以利用LoggingSystem为您创建的System属性:

  • ${PID}:当前进程ID。
  • ${LOG_FILE}:是否在Boot的外部配置中设置logging.file.name
  • ${LOG_PATH}:是否在Boot的外部配置中设置了logging.file.path(表示用于存放日志文件的目录)。
  • ${LOG_EXCEPTION_CONVERSION_WORD}:是否在Boot的外部配置中设置logging.exception-conversion-word
  • ${ROLLING_FILE_NAME_PATTERN}:是否在Boot的外部配置中设置logging.pattern.rolling-file-name

通过使用自定义的Logback转换器,Spring Boot还可以在控制台上提供一些不错的ANSI颜色终端输出(但不在日志文件中)。例如在defaults.xml中的CONSOLE_LOG_PATTERN配置。

如果Groovy在类路径上,那么您也应该能够使用logback.groovy配置Logback 。如果存在,则优先考虑此设置。

Groovy配置不支持Spring扩展。将不会检测logback-spring.groovy文件。

配置仅文件输出的Logback

如果要禁用控制台日志记录并且仅将输出写入文件,则需要一个logback-spring.xml导入file-appender.xml但不导入console-appender.xml的自定义,如以下示例所示:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
    <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
    <root level="INFO">
        <appender-ref ref="FILE" />
    </root>
</configuration>

您还需要将logging.file.name添加到application.properties中,如以下示例所示:

logging.file.name=myapplication.log

9.8.2。配置Log4j进行日志记录

如果Log4j2在类路径上,则Spring Boot支持Log4j2进行日志记录配置。如果使用启动器来组装依赖项,则必须排除Logback,然后改为包括log4j2。如果您不使用启动器,还需要提供至少spring-jclLog4j2

最简单的方法可能是通过启动器,即使它需要对排除对象进行微调。以下示例显示了如何在Maven中设置启动器:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

以下示例显示了在Gradle中设置启动器的一种方法:

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile 'org.springframework.boot:spring-boot-starter-log4j2'
}

configurations {
    all {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
}

Log4j启动器将依赖关系集中在一起,以满足常见的日志记录要求(例如Tomcat使用java.util.logging,但配置Log4j2输出)。

为确保将使用java.util.logging进行的调试日志记录路由到Log4j2中,请将系统属性java.util.logging.manager设置为 org.apache.logging.log4j.jul.LogManager,以配置其JDK日志记录适配器。

使用YAML或JSON配置Log4j2

除了默认的XML配置格式外,Log4j2还支持YAML和JSON配置文件。要将Log4j2配置为使用备用配置文件格式,请将适当的依赖项添加到类路径中,并命名您的配置文件以匹配您选择的文件格式,如以下示例所示:

格式 依赖项 文件名称
YAML com.fasterxml.jackson.core:jackson-databind +com.fasterxml.jackson.dataformat:jackson-dataformat-yaml log4j2.yaml +log4j2.yml
JSON com.fasterxml.jackson.core:jackson-databind log4j2.json +log4j2.jsn
posted @ 2019-11-28 09:36  流星<。)#)))≦  阅读(534)  评论(0编辑  收藏  举报