Spring Boot框架学习 - Spring Boot Web Application 补充

Spring Boot框架学习 - Spring Boot Web Application 补充,第1张

Spring Boot框架学习 - Spring Boot Web Application 补充

接上一篇博客:https://blog.csdn.net/qq_43605444/article/details/122307261?spm=1001.2014.3001.5502

1.2 JAX-RS 和 Jersey

如果您更喜欢 REST 端点的 JAX-RS 编程模型,您可以使用可用的实现之一而不是 Spring MVC。 Jersey 和 Apache CXF 开箱即用。 CXF 要求您在应用程序上下文中将其 Servlet 或 Filter 注册为 @Bean。 Jersey 有一些原生的 Spring 支持,所以我们还在 Spring Boot 中为它提供了自动配置支持,以及一个 starter。

要开始使用 Jersey,请将 spring-boot-starter-jersey 作为依赖项包含在内,然后您需要一个 ResourceConfig 类型的 @Bean,您可以在其中注册所有端点,如以下示例所示:

import org.glassfish.jersey.server.ResourceConfig;

import org.springframework.stereotype.Component;

@Component
public class MyJerseyConfig extends ResourceConfig {

    public MyJerseyConfig() {
        register(MyEndpoint.class);
    }

}

警告:Jersey 对扫描可执行档案的支持相当有限。 例如,当运行一个可执行的 war 文件时,它无法扫描在完全可执行的 jar 文件或 WEB-INF/classes 中找到的包中的端点。 为避免此限制,不应使用 packages 方法,应使用 register方法单独注册端点,如前面的示例所示。

对于更高级的自定义,您还可以注册任意数量的实现 ResourceConfigCustomizer 的 bean。

所有注册的端点都应该是带有 HTTP 资源注解(@GET 和其他)的 @Components,如以下示例所示:

import javax.ws.rs.GET;
import javax.ws.rs.Path;

import org.springframework.stereotype.Component;

@Component
@Path("/hello")
public class MyEndpoint {

    @GET
    public String message() {
        return "Hello";
    }

}

由于 Endpoint 是一个 Spring @Component,它的生命周期由 Spring 管理,你可以使用 @Autowired 注解注入依赖,使用 @Value 注解注入外部配置。 默认情况下,Jersey servlet 已注册并映射到 /*。 您可以通过将 @ApplicationPath 添加到您的 ResourceConfig 来更改映射。

默认情况下,Jersey 被设置为一个名为 jerseyServletRegistration 的 ServletRegistrationBean 类型的 @Bean 中的 servlet。 默认情况下,servlet 被延迟初始化,但您可以通过设置 spring.jersey.servlet.load-on-startup 来自定义该行为。 您可以通过创建自己的同名 bean 来禁用或覆盖该 bean。 您还可以通过设置 spring.jersey.type=filter(在这种情况下,要替换或覆盖的 @Bean 是 jerseyFilterRegistration)来使用过滤器而不是 servlet。 过滤器有一个@Order,你可以用 spring.jersey.filter.order 设置它。 当使用 Jersey 作为过滤器时,必须存在一个 servlet 来处理任何未被 Jersey 拦截的请求。 如果您的应用程序不包含此类 servlet,您可能希望通过将 server.servlet.register-default-servlet 设置为 true 来启用默认 servlet。 通过使用 spring.jersey.init.* 指定属性映射,可以为 servlet 和过滤器注册提供 init 参数。

1.3 嵌入式 Servlet 容器支持

对于 servlet 应用程序,Spring Boot 包括对嵌入式 Tomcat、Jetty 和 Undertow 服务器的支持。 大多数开发人员使用适当的“Starter”来获取完全配置的实例。 默认情况下,嵌入式服务器在端口 8080 上侦听 HTTP 请求。

1.3.1 Servlets、过滤器和监听器

使用嵌入式 servlet 容器时,您可以通过使用 Spring bean 或扫描 servlet 组件,从 servlet 规范中注册 servlet、过滤器和所有侦听器(例如 HttpSessionListener)。

1、将 Servlet、过滤器和监听器注册为 Spring Beans

任何属于 Spring bean 的 Servlet、Filter 或 servlet *Listener 实例都向嵌入式容器注册。 如果您想在配置期间引用 application.properties 中的值,这会特别方便。

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

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

让过滤器 bean 无序通常是安全的。 如果需要特定的顺序,您应该使用 @Order 注解过滤器或使其实现 Ordered。 您不能通过使用 @Order 注解其 bean 方法来配置过滤器的顺序。 如果您无法更改 Filter 类以添加 @Order 或实现 Ordered,则必须为 Filter 定义 FilterRegistrationBean 并使用 setOrder(int) 方法设置注册 bean 的顺序。 避免配置在 Ordered.HIGHEST_PRECEDENCE 读取请求正文的过滤器,因为它可能会违反应用程序的字符编码配置。 如果 servlet 过滤器包装请求,则应使用小于或等于 OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER 的顺序对其进行配置。

要查看应用程序中每个过滤器的顺序,请为 Web 日志记录组 (logging.level.web=debug) 启用调试级别日志记录。 注册过滤器的详细信息,包括它们的顺序和 URL 模式,将在启动时记录。

警告:注册过滤器 bean 时要小心,因为它们在应用程序生命周期的早期就被初始化。 如果您需要注册与其他 bean 交互的过滤器,请考虑改用 DelegatingFilterProxyRegistrationBean。

1.3.2 Servlet 上下文初始化

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

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

1、扫描 Servlets、过滤器和监听器

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

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

1.3.3 ServletWebServerApplicationContext

在底层,Spring Boot 使用不同类型的 ApplicationContext 来支持嵌入式 servlet 容器。 ServletWebServerApplicationContext 是一种特殊类型的 WebApplicationContext,它通过搜索单个 ServletWebServerFactory bean 来引导自身。 通常 TomcatServletWebServerFactory、JettyServletWebServerFactory 或 UndertowServletWebServerFactory 已被自动配置。

您通常不需要了解这些实现类。 大多数应用程序都是自动配置的,并且代表您创建了适当的 ApplicationContext 和 ServletWebServerFactory。

1.3.4 定制嵌入式 Servlet 容器

可以使用 Spring Environment 属性配置常见的 servlet 容器设置。 通常,您会在 application.properties 或 application.yaml 文件中定义属性。

常见的服务器设置包括:

  • 网络设置:监听传入 HTTP 请求的端口(server.port)、绑定到 server.address 的接口地址等。
  • 会话设置:会话是否持久(server.servlet.session.persistent)、会话超时(server.servlet.session.timeout)、会话数据的位置(server.servlet.session.store-dir)和会话 cookie 配置(server.servlet.session.cookie.*)。
  • 错误管理:错误页面的位置(server.error.path)等。
  • 安全证书(SSL)
  • HTTP 压缩

Spring Boot 尽可能地尝试公开通用设置,但这并不总是可行的。 对于这些情况,专用命名空间提供特定于服务器的定制(参见 server.tomcat 和 server.undertow)。 例如,可以使用嵌入式 servlet 容器的特定功能配置访问日志。

有关完整列表,请参阅 ServerProperties 类。

同站点 cookie

Web 浏览器可以使用 SameSite cookie 属性来控制是否以及如何在跨站点请求中提交 cookie。 该属性与现代 Web 浏览器特别相关,这些浏览器已开始更改缺少该属性时使用的默认值。

如果要更改会话 cookie 的 SameSite 属性,可以使用 server.servlet.session.cookie.same-site 属性。 自动配置的 Tomcat、Jetty 和 Undertow 服务器支持此属性。 它还用于配置基于 Spring Session servlet 的 SessionRepository bean。

例如,如果您希望会话 cookie 的 SameSite 属性为 None,则可以将以下内容添加到 application.properties 或 application.yaml 文件中:

server.servlet.session.cookie.same-site=none

如果要更改添加到 HttpServletResponse 的其他 cookie 的 SameSite 属性,可以使用 cookieSameSiteSupplier。 向 cookieSameSiteSupplier 传递一个 cookie,并且可能返回一个 SameSite 值,或者返回 null。

您可以使用多种便利的工厂和过滤方法来快速匹配特定的 cookie。 例如,添加以下 bean 将自动为名称与正则表达式 myapp.* 匹配的所有 cookie 应用 Lax 的 SameSite。

import org.springframework.boot.web.servlet.server.cookieSameSiteSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MySameSiteConfiguration {

    @Bean
    public cookieSameSiteSupplier applicationcookieSameSiteSupplier() {
        return cookieSameSiteSupplier.ofLax().whenHasNameMatching("myapp.*");
    }

}
程序化定制

如果您需要以编程方式配置您的嵌入式 servlet 容器,您可以注册一个实现 WebServerFactoryCustomizer 接口的 Spring bean。 WebServerFactoryCustomizer 提供对 ConfigurableServletWebServerFactory 的访问,其中包括许多自定义设置器方法。 以下示例显示了以编程方式设置端口:

import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;

@Component
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer {

    @Override
    public void customize(ConfigurableServletWebServerFactory server) {
        server.setPort(9000);
    }

}

TomcatServletWebServerFactory、JettyServletWebServerFactory 和 UndertowServletWebServerFactory 是 ConfigurableServletWebServerFactory 的专用变体,它们分别为 Tomcat、Jetty 和 Undertow 提供了额外的自定义设置方法。 以下示例显示如何自定义 TomcatServletWebServerFactory 以提供对 Tomcat 特定配置选项的访问:

import java.time.Duration;

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyTomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer {

    @Override
    public void customize(TomcatServletWebServerFactory server) {
        server.addConnectorCustomizers((connector) -> connector.setAsyncTimeout(Duration.ofSeconds(20).toMillis()));
    }

}
直接自定义 ConfigurableServletWebServerFactory

对于需要您从 ServletWebServerFactory 扩展的更高级用例,您可以自己公开此类类型的 bean。

为许多配置选项提供了设置器。 如果您需要做一些更奇特的事情,还提供了几个受保护的方法“钩子”。 有关详细信息,请参阅源代码文档。

自动配置的定制器仍适用于您的定制工厂,因此请谨慎使用该选项。

1.3.5 JSP 限制

在运行使用嵌入式 servlet 容器(并打包为可执行存档)的 Spring Boot 应用程序时,JSP 支持存在一些限制。

  • 使用 Jetty 和 Tomcat,如果您使用 war 打包,它应该可以工作。 当使用 java -jar 启动时,可执行 war 将起作用,并且还可以部署到任何标准容器。 使用可执行 jar 时不支持 JSP。
  • Undertow 不支持 JSP。
  • 创建自定义 error.jsp 页面不会覆盖错误处理的默认视图。 应改用自定义错误页面。

文章参考:https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#web

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/5696497.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存