Spring Boot 参考指南(开发Web应用程序)

代码探风鹤
• 阅读 4009

27. 开发Web应用程序

Spring Boot非常适合web应用程序开发,通过使用嵌入式Tomcat、Jetty、Undertow或Netty,你可以创建一个自包含的HTTP服务器。大多数web应用程序都使用spring-boot-starter-web模块来快速启动和运行,你还可以选择使用spring-boot-starter-webflux模块构建reactive web应用程序。

如果你还没有开发过一个Spring Boot web应用程序,你可以按照入门部分中的“Hello World!”示例进行操作。

27.1 Spring Web MVC Framework

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

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

@RestController
@RequestMapping(value="/users")
public class MyRestController {

    @RequestMapping(value="/{user}", method=RequestMethod.GET)
    public User getUser(@PathVariable Long user) {
        // ...
    }

    @RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
    List<Customer> getUserCustomers(@PathVariable Long user) {
        // ...
    }

    @RequestMapping(value="/{user}", method=RequestMethod.DELETE)
    public User deleteUser(@PathVariable Long user) {
        // ...
    }

}

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

27.1.1 Spring MVC自动配置

Spring Boot为大多数应用程序提供了良好的Spring MVC自动配置。

自动配置在Spring的默认设置之上添加了以下特性:

  • 包含ContentNegotiatingViewResolverBeanNameViewResolver bean。
  • 支持提供静态资源,包括支持WebJars(稍后将在本文中介绍)。
  • ConverterGenericConverterFormatter bean的自动注册。
  • 支持HttpMessageConverters(稍后将在本文中介绍)。
  • MessageCodesResolver的自动注册(稍后将在本文中介绍)。
  • 静态index.html支持。
  • 支持自定义图标(稍后将在本文中介绍)。
  • 自动使用ConfigurableWebBindingInitializer bean(稍后将在本文中介绍)。

如果你想保留Spring Boot MVC特性,并且希望添加额外的MVC配置(拦截器、格式化器、视图控制器和其他特性),你可以添加自己的@Configuration类的WebMvcConfigurer类型,但没有@EnableWebMvc,如果希望提供RequestMappingHandlerMappingRequestMappingHandlerAdapterExceptionHandlerExceptionResolver的定制实例,可以声明一个WebMvcRegistrationsAdapter实例来提供这些组件。

如果你想完全控制Spring MVC,可以添加自己的@EnableWebMvc注解的@Configuration

27.1.2 HttpMessageConverters

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

如果需要添加或定制转换器,可以使用Spring Boot的HttpMessageConverters类,如下面的清单所示:

import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;

@Configuration
public class MyConfiguration {

    @Bean
    public HttpMessageConverters customConverters() {
        HttpMessageConverter<?> additional = ...
        HttpMessageConverter<?> another = ...
        return new HttpMessageConverters(additional, another);
    }

}

上下文中出现的任何HttpMessageConverter bean都被添加到转换器列表中,你还可以以同样的方式覆盖默认转换器。

27.1.3 自定义JSON序列化器和反序列化器

如果使用Jackson序列化和反序列化JSON数据,你可能想要编写自己的JsonSerializerJsonDeserializer类,定制序列化器通常通过模块向Jackson注册,但是Spring Boot提供了一个替代的@JsonComponent注解,使直接注册Spring bean变得更容易。

你可以直接在JsonSerializerJsonDeserializer实现上使用@JsonComponent注解,你还可以在包含序列化/反序列化器的类中使用它作为内部类,如下例所示:

import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;

@JsonComponent
public class Example {

    public static class Serializer extends JsonSerializer<SomeObject> {
        // ...
    }

    public static class Deserializer extends JsonDeserializer<SomeObject> {
        // ...
    }

}

ApplicationContext中的所有@JsonComponent bean都自动注册到Jackson,因为@JsonComponent是由@Component注解的,所以通常使用组件扫描规则。

Spring Boot还提供了JsonObjectSerializerJsonObjectDeserializer基类,这些基类在序列化对象时为标准Jackson版本提供了有用的替代方法,有关详细信息,请参阅Javadoc中的JsonObjectSerializerJsonObjectDeserializer

27.1.4 MessageCodesResolver

Spring MVC有一个生成错误代码的策略,用于从绑定错误中呈现错误消息:MessageCodesResolver,如果你设置spring.mvc.message-codes-resolver.format属性PREFIX_ERROR_CODEPOSTFIX_ERROR_CODE,Spring Boot为你创建一个(参见DefaultMessageCodesResolver.Format中的枚举)。

27.1.5 静态内容

默认情况下,Spring Boot从类路径或ServletContext根目录中提供静态内容,目录名为/static(或/public/resources/META-INF/resources),它使用来自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.resources.static-locations属性定制静态资源位置(用目录位置列表替换默认值),根Servlet上下文路径"/"也作为位置自动添加。

除了前面提到的“标准”静态资源位置之外,Webjars内容还有一个特殊的例子,任何在/webjars/**中具有路径的资源都可以从jar文件中获取,如果它们被打包成webjars格式的话。

如果你的应用程序打包为jar,那么不要使用src/main/webapp目录,虽然这个目录是一个通用标准,但它只与war打包一起工作,并且如果你生成一个jar,它会被大多数构建工具默默忽略。

Spring Boot还支持Spring MVC提供的高级资源处理特性,允许用例(比如cache-busting的静态资源)或使用webjar的版本无关url。

要为webjar使用版本无关的url,请添加webjar-locator-core依赖项,然后声明你的Webjar,以jQuery为例,添加"/webjars/jquery/jquery.min.js"的结果是"/webjars/jquery/x.y.z/jquery.min.js",x.y.z的地方是Webjar版本。

如果使用JBoss,则需要声明webjar—locator—JBoss—vfs依赖项,而不是webjar—locator-core,否则,所有Webjars解析为404

为了使用cache busting,下面的配置为所有静态资源配置cache busting解决方案,有效地添加了内容散列,例如<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>,在URL中:

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
由于ResourceUrlEncodingFilter自动为Thymeleaf和FreeMarker配置,所以到资源的链接在运行时在模板中被重写,在使用JSP时,应该手动声明这个过滤器,其他的模板引擎目前不被自动支持,但是可以使用自定义模板宏/助手和ResourceUrlProvider的使用。

当使用JavaScript模块加载器动态加载资源时,不允许重命名文件,这就是为什么其他策略也得到支持并可以结合使用,“固定”策略在URL中添加静态版本字符串,而不更改文件名,如下例所示:

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12

在这种配置下,位于"/js/lib/"下的JavaScript模块使用固定的版本控制策略(“/v12/js/lib/mymodule.js”),而其他资源仍然使用内容控制策略(<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>)。

有关更多支持的选项,请参阅ResourceProperties

这个特性已经在一个专门的博客帖子和Spring Framework参考文档中进行了详细描述。

27.1.6 欢迎页面

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

27.1.7 自定义图标

Spring Boot在配置的静态内容位置和类路径根目录中查找favicon.ico(按顺序),如果存在这样的文件,它将自动用作应用程序的图标。

27.1.8 路径匹配和内容协商

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


上一篇:日志记录
下一篇:安全
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表(关于日期时间时分秒显示不出来)
在使用皕杰报表设计器时,数据据里面是日期型,但当你web预览时候,发现有日期时间类型的数据时分秒显示不出来,只有年月日能显示出来,时分秒显示为0:00:00。1.可以使用tochar解决,数据集用selecttochar(flowdate,"yyyyMMddHH:mm:ss")fromtablename2.也可以把数据库日期类型date改成timestamp
Wesley13 Wesley13
3年前
1、SpringMVC的简介
1.1什么是SpringMVCSpringMVC属于SpringFrameWork的后续产品,已经融合在SpringWebFlow里面。Spring框架提供了构建Web应用程序的全功能MVC模块。使用Spring可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或
Stella981 Stella981
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(