• 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
  • 相关阅读:
    06.django升级打怪学习记
    05.django升级打怪学习记
    04.django升级打怪学习记
    03.django升级打怪学习记
    02.django升级打怪学习记
    python学习手册笔记——39.元类
    python学习手册笔记——35.异常的设计
    关于我
    [Jenkins]Console Output中文显示问号的问题解决
    [Jenkins]JDK版本过高导致的java.io.IOException: Remote call on xxxx failed
  • 原文地址:https://www.cnblogs.com/huangwenjie/p/11946979.html
Copyright © 2020-2023  润新知