Spring Boot对Servlet web应用的支持

06-25 1116阅读

https://docs.spring.io/spring-boot/docs/3.2.0/reference/htmlsingle/#web.servlet

Spring Web MVC 框架

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

以下代码展示了一个典型的 @RestController,它提供 JSON 数据:

import java.util.List;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/users")
public class MyRestController {
    private final UserRepository userRepository;
    private final CustomerRepository customerRepository;
    public MyRestController(UserRepository userRepository, CustomerRepository customerRepository) {
        this.userRepository = userRepository;
        this.customerRepository = customerRepository;
    }
    @GetMapping("/{userId}")
    public User getUser(@PathVariable Long userId) {
        return this.userRepository.findById(userId).get();
    }
    @GetMapping("/{userId}/customers")
    public List getUserCustomers(@PathVariable Long userId) {
        return this.userRepository.findById(userId).map(this.customerRepository::findByUser).get();
    }
    @DeleteMapping("/{userId}")
    public void deleteUser(@PathVariable Long userId) {
        this.userRepository.deleteById(userId);
    }
}

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

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.function.RequestPredicate;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;
import static org.springframework.web.servlet.function.RequestPredicates.accept;
import static org.springframework.web.servlet.function.RouterFunctions.route;
@Configuration(proxyBeanMethods = false)
public class MyRoutingConfiguration {
    private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);
    @Bean
    public RouterFunction routerFunction(MyUserHandler userHandler) {
        return route()
                .GET("/{user}", ACCEPT_JSON, userHandler::getUser)
                .GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
                .DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
                .build();
    }
}
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.function.ServerRequest;
import org.springframework.web.servlet.function.ServerResponse;
@Component
public class MyUserHandler {
    public ServerResponse getUser(ServerRequest request) {
        ...
        return ServerResponse.ok().build();
    }
    public ServerResponse getUserCustomers(ServerRequest request) {
        ...
        return ServerResponse.ok().build();
    }
    public ServerResponse deleteUser(ServerRequest request) {
        ...
        return ServerResponse.ok().build();
    }
}

Spring MVC 是 Spring 框架的核心部分。

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

Spring MVC 自动配置

Spring Boot 为 Spring MVC 提供了自动配置,这对于大多数应用程序而言非常有用。它取代了使用 @EnableWebMvc 的需求,并且这两个不能一起使用。除了 Spring MVC 的默认设置外,自动配置还提供了以下功能:

  • 包含 ContentNegotiatingViewResolver 和 BeanNameViewResolver bean。
  • 支持提供静态资源,包括支持 WebJars。
  • 自动注册 Converter、GenericConverter 和 Formatter bean。
  • 支持 HttpMessageConverters。
  • 自动注册 MessageCodesResolver。
  • 支持静态的 index.html。
  • 自动使用 ConfigurableWebBindingInitializer bean。

    如果你想保留这些 Spring Boot MVC 自定义,并进行更多 MVC 自定义(例如拦截器、格式化程序、视图控制器和其它功能),则可以添加你自己的类型为 WebMvcConfigurer 的 @Configuration 类,但不使用 @EnableWebMvc。

    如果你想提供 RequestMappingHandlerMapping、RequestMappingHandlerAdapter 或 ExceptionHandlerExceptionResolver 的自定义实例,同时仍保留 Spring Boot MVC 的自定义设置,则可以声明一个类型为 WebMvcRegistrations 的 bean,并使用它来提供这些组件的自定义实例。这些自定义实例将接受 Spring MVC 的进一步初始化和配置。如果要参与(且希望)覆盖后续的处理,则应该使用 WebMvcConfigurer。

    如果你不想使用自动配置,并希望完全控制 Spring MVC,请添加你自己的带有 @EnableWebMvc 注解的 @Configuration。另外,也可以添加你自己的带有 @Configuration 注解的 DelegatingWebMvcConfiguration。

    Spring MVC 转换服务(Conversion Service)

    Spring MVC 使用的 ConversionService 与用于从 application.properties 或 application.yaml 文件中转换值的 ConversionService 不同。这意味着 Period、Duration 和 DataSize 转换器不可用,并且 @DurationUnit 和 @DataSizeUnit 注解将被忽略。

    如果你想自定义 Spring MVC 使用的 ConversionService,可以提供一个带有 addFormatters 方法的 WebMvcConfigurer bean。从该方法中,你可以注册任何你喜欢的转换器,或者可以委托给 ApplicationConversionService 上可用的静态方法。

    还可以使用 spring.mvc.format.* 配置属性来定制转换。如果未进行配置,则使用以下默认值:

    Spring Boot对Servlet web应用的支持

    HttpMessageConverters

    Spring MVC 使用 HttpMessageConverter 接口来转换 HTTP 请求和响应。它提供了合理的默认设置。例如,对象可以自动转换为 JSON(通过使用 Jackson 库)或 XML(如果可用,则使用 Jackson XML 扩展,否则使用 JAXB)。默认情况下,字符串以 UTF-8 编码。

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

    import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.HttpMessageConverter;
    @Configuration(proxyBeanMethods = false)
    public class MyHttpMessageConvertersConfiguration {
        @Bean
        public HttpMessageConverters customConverters() {
            HttpMessageConverter additional = new AdditionalHttpMessageConverter();
            HttpMessageConverter another = new AnotherHttpMessageConverter();
            return new HttpMessageConverters(additional, another);
        }
    }
    

    上下文中存在的任何 HttpMessageConverter bean 都会被添加到转换器列表中。你也可以用相同的方式覆盖默认转换器。

    MessageCodesResolver

    Spring MVC 有一个用于从绑定错误中生成错误代码以呈现错误消息的策略:MessageCodesResolver。如果你设置了 spring.mvc.message-codes-resolver-format 属性为 PREFIX_ERROR_CODE 或 POSTFIX_ERROR_CODE,Spring Boot 将为您创建一个。

    静态内容

    默认情况下,Spring Boot 从类路径中的名为 /static(或 /public 或 /resources 或 /META-INF/resources)的目录或从 ServletContext 的根目录中提供静态内容。它使用 Spring MVC 的 ResourceHttpRequestHandler,因此你可以通过添加自己的 WebMvcConfigurer 并覆盖 addResourceHandlers 方法来修改该行为。

    在独立的 Web 应用程序中,容器中的默认 servlet 未启用。可以通过使用 server.servlet.register-default-servlet 属性来启用它。

    默认 servlet 作为回退机制,如果 Spring 决定不处理它,则从 ServletContext 的根目录提供内容。在大多数情况下,这不会发生(除非你修改了默认的 MVC 配置),因为 Spring 总是可以通过 DispatcherServlet 处理请求。

    默认情况下,资源映射到 /**,但你可以使用 spring.mvc.static-path-pattern 属性进行调整。例如,将所有资源重新定位到 /resources/**可以按照以下方式实现:

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

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

    除了前面提到的“标准”静态资源位置外,还对 Webjars 内容进行了特殊处理。默认情况下,如果以 Webjars 格式打包,则任何路径为 /webjars/** 的资源都从 jar 文件中提供。可以使用 spring.mvc.webjars-path-pattern 属性自定义路径。

    提示:如果你的应用程序被打包为 jar 文件,请不要使用 src/main/webapp 目录。尽管此目录是一个常见的标准,但它仅适用于 war 打包,并且如果你生成 jar 文件,大多数构建工具都会静默忽略它。

    Spring Boot 还支持 Spring MVC 提供的高级资源处理功能,允许使用诸如打破缓存的静态资源或使用 Webjars 的无版本 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-jboss-vfs 依赖项,而不是 webjars-locator-core。否则,所有 Webjars 都将解析为 404。

    要使用缓存打破功能,以下配置为所有静态资源配置了缓存打破解决方案,有效地在 URL 中添加了一个内容哈希,例如

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]