Spring Boot笔记 #07# Web

翻译自:https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#web

Spring Boot非常适合web应用程序开发。您可以使用嵌入式Tomcat、Jetty、Undertow或Netty创建一个自包含的(self-contained)HTTP服务器。大多数web应用程序使用spring-boot-starter-web模块快速启动并运行。您还可以选择使用spring-boot-starter-webflux模块构建反应式web应用程序。

如果您还没有开发过Spring Boot web应用程序,可以参考“Hello World!”入门部分的示例

1. Servlet Web Applications

如果您想构建基于servlet的web应用程序,可以利用Spring Boot对Spring MVC或Jersey的自动配置。

1.1. The “Spring Web MVC Framework”

Spring Web MVC框架(通常被称为“SpringMVC”)是一个丰富的“模型(model)-视图(view)-控制器(controller)”Web框架。Spring MVC允许您创建特殊的@Controller@RestController bean来处理传入的HTTP请求。控制器中的方法通过@RequestMapping注释映射到HTTP。

下面的代码显示了提供JSON数据的典型@RestController

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("/{user}")
    public User getUser(@PathVariable Long userId) {
        return this.userRepository.findById(userId).get();
    }

    @GetMapping("/{user}/customers")
    public List<Customer> getUserCustomers(@PathVariable Long userId) {
        return this.userRepository.findById(userId).map(this.customerRepository::findByUser).get();
    }

    @DeleteMapping("/{user}")
    public void deleteUser(@PathVariable Long userId) {
        this.userRepository.deleteById(userId);
    }

}

Spring MVC是核心Spring框架的一部分,详细信息可在参考文档中找到。spring.io/guides上还提供了几个关于Spring MVC的指南。

1.1.1. Spring MVC Auto-configuration

Spring Boot为Spring MVC提供了自动配置(auto-configuration),可用于大多数应用程序。

自动配置在Spring默认设置的基础上增加了以下功能:

  • Inclusion(包含) of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
  • Automatic registration of ConverterGenericConverter, and Formatter beans.
  • Static index.html support.

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

如果您想提供RequestMappingHandlerMappingRequestMappingHandlerAdapterExceptionHandlerExceptionResolver的自定义实例,并且仍然保留Spring Boot MVC自定义设置,那么可以声明WebMvcRegistrations类型的bean,并使用它来提供这些组件的自定义实例。

如果你想完全控制Spring MVC,你可以添加你自己的@Configuration注释@EnableWebMvc,或者添加你自己的@Configuration注释DelegatingWebMvcConfiguration配置,如@EnableWebMvc的Javadoc所述。

1.1.2. HttpMessageConverters

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

1.1.5. Static Content

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

在一个独立的web应用程序中,容器中的默认servlet也会被启用,并充当后备服务,如果Spring决定不处理它,则从ServletContext的根目录提供内容。大多数情况下,这种情况不会发生(除非修改默认的MVC配置),因为Spring总是可以通过DispatcherServlet处理请求。

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

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

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

1.1.6. Welcome Page

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

1.1.7. Path Matching and Content Negotiation

Spring MVC可以通过查看请求路径并将其与应用程序中定义的映射匹配(例如,控制器方法上的@GetMapping注释),将传入的HTTP请求映射到处理程序。

Spring Boot默认选择禁用后缀模式匹配,这意味着像“GET /projects/spring-boot.json”这样的请求将不会与@GetMapping(“/projects/spring-boot”)映射匹配。这被认为是Spring MVC应用程序的最佳实践。这个特性在过去主要用于HTTP客户机,这些客户机没有发送正确的“Accept”请求头;我们需要确保向客户端发送正确的内容类型。如今,内容协商(Content Negotiation)更加可靠。

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

spring.mvc.contentnegotiation.favor-parameter=true

或者,如果您更喜欢使用不同的参数名称:

spring.mvc.contentnegotiation.favor-parameter=true
spring.mvc.contentnegotiation.parameter-name=myparam

大多数标准media类型都支持开箱即用(out-of-the-box),但您也可以定义新的media类型:

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

从Spring Framework 5.3开始,Spring MVC支持几种实现策略,用于将请求路径匹配到控制器处理程序。它以前只支持AntPathMatcher策略,但现在还提供PathPatternParser。Spring Boot现在提供了一个配置属性来选择和选择新策略:

spring.mvc.pathmatch.matching-strategy=path-pattern-parser

或者更详细的说明为什么你应该考虑这个新的实现,请看专门的博客文章

1.1.10. Error Handling

默认情况下,Spring Boot提供了一个/error映射,以合理的方式处理所有错误,并在servlet容器中注册为“全局(global)”错误页。对于机器客户端,它会生成一个JSON响应,其中包含错误、HTTP状态和异常消息的详细信息。对于浏览器客户端,有一个以HTML格式呈现相同数据的“白标签(whitelabel)”错误视图(要自定义它,请添加一个解决errorView)。

如果要自定义默认错误处理行为,可以设置许多server.error属性。请参阅附录中的“服务器属性”部分。

要完全替换默认行为,可以实现ErrorController并注册该类型的bean定义,或者添加ErrorAttributes类型的bean以使用现有机制,但替换内容。

1.3. Embedded Servlet Container Support

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

1.3.4. Customizing Embedded Servlet Containers

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

常见的服务器设置包括:

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

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

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

SameSite Cookies

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

 

posted @ 2022-03-09 15:56  xkfx  阅读(121)  评论(0编辑  收藏  举报