封面
版权信息
内容提要
译者序
关于本书
作者简介
关于本书封面
前言
致谢
第1部分 Spring基础
第1章 Spring起步
1.1 什么是Spring
1.2 初始化Spring应用
1.3 编写Spring应用
1.4 俯瞰Spring风景线
小结
第2章 开发Web应用
2.1 展现信息
2.2 处理表单提交
2.3 校验表单输入
2.4 使用视图控制器
2.5 选择视图模板库
小结
第3章 使用数据
3.1 使用JDBC读取和写入数据
3.2 使用Spring Data JDBC
3.3 使用Spring Data JPA持久化数据
小结
第4章 使用非关系型数据
4.1 使用Cassandra存储库
4.2 编写MongoDB存储库
小结
第5章 保护Spring
5.1 启用Spring Security
NOTE
要想通过这个认证,你需要一个用户名和密码。用户名为user,而密码则是随机生成的,它会写入到应用的日志文件中。日志条目大致如下所示:
2023-08-01 09:05:28
5.2 配置Spring Security
5.3 保护Web请求
5.4 实现方法级别的安全
5.5 了解用户是谁
小结
第6章 使用配置属性
6.1 细粒度地调整自动配置
NOTE
需要注意,在将属性设置为环境变量的时候,命名风格略有不同,这样做是为了适应操作系统对环境变量名称的限制。不过,没有关系,Spring能够将其挑选出来,并将SERVER_PORT解析为server.port。
2023-02-07 01:24:49
6.2 创建自己的配置属性
6.3 使用profile进行配置
小结
第2部分 Spring集成
第7章 创建REST服务
7.1 编写RESTful控制器
NOTE
@RestController注解会告诉Spring,在控制器中,所有处理器方法的返回值都要直接写入响应体,而不是将值放到模型中并传递给一个视图以便渲染。
2023-07-31 08:33:18
NOTE
Web浏览器会阻止客户端消费该API
2023-07-31 08:33:08
NOTE
我们可能还想使用像curl或HTTPie这样的命令行工具来探测该API
2023-07-31 08:34:18
NOTE
也可以添加一个CommandLineRunner bean,使用测试数据预加载数据库
2023-07-31 08:34:49
NOTE
201 (CREATED)的HTTP状态更具有描述性。
2023-07-31 09:13:40
NOTE
HTTP PUT或PATCH
2023-07-31 09:15:22
NOTE
PUT真正的目的是执行大规模的替换(replacement)操作,而不是更新操作。而HTTP PATCH的目的是对资源数据打补丁或进行局部更新。
2023-07-31 09:16:02
NOTE
还有更多的方式来实现PATCH
2023-07-31 09:22:12
NOTE
我们没有办法添加或移除集合的子集。客户端如果想要添加或移除集合中的条目,必须将变更的完整集合发送到服务器端。
2023-07-31 09:22:39
NOTE
最终的效果都是资源不存在,所以在删除之前资源是否存在并不重要。另外一种办法是让deleteOrder()返回ResponseEntity,在资源不存在的时候将响应体设置为null并将HTTP状态码设置为NOT FOUND
2023-07-31 09:31:29
7.2 启用数据后端服务
NOTE
Spring Data有一种特殊的能力,能够基于我们定义的接口自动创建存储库实现。但是Spring Data还有另外一项技巧,能够帮助我们定义应用的API。
2023-08-01 09:07:16
NOTE
不管你是否相信,对于已经使用Spring Data自动生成存储库的项目,只需要完成这一步就能对外暴露REST API了
2023-07-31 09:33:58
NOTE
借助HATEOAS,我们不用在客户端中对API的细节进行编码并让客户端为每个请求构建URL。
2023-07-31 09:35:52
NOTE
本书中,我们不再浪费时间深入探究Spring Data REST所创建的每个端点和可选项。
2023-07-31 09:36:10
NOTE
在暴露taco端点时,还是出现了一点问题。
2023-07-31 09:39:32
NOTE
Spring Data REST还暴露了一个主资源(home resource),这个资源包含了所有端点的链接。
2023-07-31 09:43:58
NOTE
通过为Taco添加一个简单的注解,我们就能调整关系名和路径:
2023-07-31 09:44:31
NOTE
page参数是从0开始计算的,也就是说page值为1的时候,会请求次页的数据。
2023-07-31 09:46:41
7.3 消费REST服务
NOTE
这些API就像薛定谔的猫。在发起请求之前,我们并不知道这些API是否活跃,也不知道它们是否返回HTTP 404响应。
2023-07-31 09:48:28
NOTE
Spring应用可以采用多种方式来消费REST API。●RestTemplate:由Spring核心框架提供的简单、同步REST客户端。●Traverson:对Spring RestTemplate的包装,由Spring HATEOAS提供的支持超链接、同步的REST客户端,其灵感来源于同名的JavaScript库。●WebClient:反应式、异步REST的客户端。
2023-07-31 09:49:17
NOTE
的单调工作中解放出来。RestTemplat提供了41个与REST资源交互的方法。我不会详细介绍它所提供的所有方法,而是只考虑12个独立的操作,这些操作的重载形式组成了完整的41个方法。这12个操作如表7.2所示。
2023-07-31 09:50:30
NOTE
它接收一个String类型的URL并使用可变列表来指定URL变量。
2023-07-31 09:52:42
NOTE
到占位符中。getForObject()方法的第二个参数是响应应该绑定的类型。在本例中,响应数据(很可能是JSON格式)应该被反序列化为要返回的Ingredient对象。
2023-07-31 09:52:57
小结
第8章 保护REST
8.1 OAuth 2简介
8.2 创建授权服务器
NOTE
bean方法authorizationServerSecurityFilterChain()
2023-07-31 13:40:06
NOTE
这里面大多数内容都是样板式的配置。你如果愿意,可以深入研究并做一些定制化的配置。现在,我们采用默认的配置就可以了。
2023-07-31 13:40:23
8.3 使用资源服务器保护API
8.4 开发客户端
小结
第9章 发送异步消息
NOTE
异步消息是一个应用程序向另一个应用程序间接发送消息的一种方式,这种间接性能够为通信的应用带来更松散的耦合和更大的可伸缩性。
2023-07-31 13:45:54
9.1 使用JMS发送消息
NOTE
消息代理(message broker)的通用API
2023-08-03 09:09:11
NOTE
如果你想要了解关于JMS的更多内容,请参阅Bruce Snyder、Dejan Bosanac和Rob Davies合著的ActiveMQ in Action(Manning,2011年)
2023-07-28 08:43:03
NOTE
Artemis。
2023-08-03 09:12:29
NOTE
Spring Boot会自动配置一个JmsTemplate(以及其他内容)
2023-08-03 10:26:53
NOTE
JmsTemplate能够让我们关注真正要做的事情:发送消息。
2023-08-03 10:28:19
NOTE
我们通过Taco Cloud的Web站点创建订单时,就会有一条消息发送至代理,以便将其路由至另外一个接收订单的应用
2023-08-03 13:33:05
NOTE
我们发现MessageCreator是一个函数式接口,所以可以通过lambda表达式简化sendOrder()方法:
2023-08-03 13:46:02
NOTE
为了让它能够运行,我们需要通过名为spring.jms.template.default-destination的属性声明一个默认的目的地名称。
2023-08-03 13:47:42
NOTE
如下的bean声明了Taco Cloud订单队列的Destination:
2023-08-03 13:48:40
NOTE
在需要通过JMS发送和接收消息的应用中,这个bean方法可以添加到任意的配置类里面。
2023-08-03 13:50:54
NOTE
为了良好的代码组织,最好将其添加到一个专为消息相关的配置所创建的配置类中,比如MessagingConfig
2023-08-03 13:51:11
NOTE
这里的ActiveMQQueue来源于Artemis(来自org.apache.activemq. artemis.jms.client包)。如果你使用ActiveMQ(而不是Artemis),同样会找到一个名为ActiveMQQueue的类
2023-08-03 14:00:31
NOTE
如果能够只指定要发送的对象(以及可能要用到的目的地),岂不是更简单?这其实就是convertAndSend()的工作原理
2023-08-03 14:06:32
NOTE
JmsTemplates的convertAndSend()方法简化了消息的发布,因为它不再需要Message Creator。
2023-08-03 14:10:19
NOTE
在底层,这是通过MessageConverter的实现类来完成的,它替我们完成了将对象转换成Message的任务。
2023-08-03 14:12:27
NOTE
表9.3 Spring为通用的转换任务提供了多个消息转换器(所有的消息转换器都位于org.springframework.jms.support.converter包中)
[插图]
默认情况下,将会使用SimpleMessageConverter,但是它需要被发送的对象实现Serializable。这种办法也不错,但有时候我们可能想要使用其他的消息转换器来消除这种限制,比如MappingJackson2MessageConverter。
为了使用不同的消息转换器,我们必须将选中的消息转换器实例声明为一个bean。例如,如下的bean声明将会使用MappingJackson2MessageConverter替代SimpleMessageConverter:
@Bean
public MappingJackson2MessageConverter messageConverter() {
MappingJackson2MessageConverter messageConverter =
new MappingJackson2MessageConverter();
messageConverter.setTypeIdPropertyName("_typeId");
return messageConverter;
}
2023-08-03 14:45:18
NOTE
默认情况下,将会使用SimpleMessageConverter,但是它需要被发送的对象实现Serializable。这种办法也不错,但有时候我们可能想要使用其他的消息转换器来消除这种限制,比如MappingJackson2MessageConverter。
2023-08-07 20:53:10
NOTE
这非常重要,因为这样能够让接收者知道传入的消息需要转换成什么类型。
2023-08-03 15:27:07
NOTE
消息转换器bean方法的如下代码变更会将一个合成的TacoOrder类型ID映射为TacoOrder类:
2023-08-03 15:36:52
NOTE
在接收端的应用中会配置类似的消息转换器,将TacoOrder映射为它自己能够理解的订单类型。
2023-08-03 15:43:05
NOTE
有种更简单的方案是为消息添加一个自定义的头部,让它携带订单的来源。
2023-08-07 21:31:57
NOTE
你可能会发现代码在不同的地方多次调用convertAndSend(),它们均会用到相同的MessagePostProcessor。在这种情况下,方法引用是比lambda表达式更好的方案,因为它能避免不必要的代码重复
2023-08-08 11:21:09
NOTE
通过声明JMS监听器来实现推送模式
2023-08-08 11:41:27
NOTE
消息监听器通常被视为最佳选择,因为它不会导致阻塞,并且能够快速处理多个消息
2023-08-08 11:55:18
NOTE
厨房用户界面需要在订单到达时进行缓冲,避免给厨师带来过重的负载。
2023-08-08 11:55:29
NOTE
如果消息处理器需要根据自己的时间请求更多消息,那么JmsTemplate提供的拉取模式会更加合适。
2023-08-08 11:55:46
NOTE
RabbitMQ和Kafka等较新的消息传递方案克服了这些缺点,可以用于JVM之外的其他语言和平台。让我们把JMS放在一边,看看如何使用RabbitMQ实现taco订单的消息传递
2023-08-08 11:56:08
9.2 使用RabbitMQ和AMQP
NOTE
AMQP最杰出的实现
2023-08-07 11:26:07
NOTE
JMS消息需要使用目的地名称来寻址,接收者会从这里检索消息,而AMQP消息使用交换机(exchange)和路由键(routing key)来寻址,这样可以使消息与接收者要监听的队列解耦
2023-08-07 11:39:59
NOTE
它们会接受String类型的值以指定交换机和路由键,而不像JmsTemplate那样接受目的地名称(或Destination)
2023-08-08 14:40:19
NOTE
没有接受交换机参数的方法会将消息发送至Default交换机。
2023-08-08 14:41:06
NOTE
这意味着我们可以按照相同的方式将它注入OrderApiController,在提交订单时发送订单消息
2023-08-08 14:42:38
NOTE
我们必须要通过MessageProperties来提供消息属性,但是如果我们不需要设置任何这样的属性,可以使用默认的MessageProperties实例。剩
2023-08-08 14:45:14
NOTE
至于默认的交换机,它的名字是""(也就是空字符串),这对应了RabbitMQ代理自动生成的Default交换机。与之相似,默认的路由键也是""(它的路由将会取决于交换机以及相应的绑定)。
2023-08-08 14:46:35
NOTE
Jackson2JsonMessageConverter:使用Jackson 2 JSON处理器实现对象和JSON的相互转换。●MarshallingMessageConverter:使用Spring的Marshaller和Unmarshaller进行转换。●SerializerMessageConverter:使用Spring的Serializer和Deserializer转换String和任意种类的原生对象。●SimpleMessageConverter:转换String、字节数组和Serializable类型。●ContentTypeDelegatingMessageConverter:基于contentType头信息,将转换功能委托给另外一个MessageConverter。●MessagingMessageConverter:将消息转换功能委托给另外一个MessageConverter,并将头信息的转换委托给AmqpHeaderConverter。
2023-08-08 14:47:24
NOTE
Spring Boot的自动配置功能会发现这个bean,并将它注入RabbitTemplate,替换默认的消息转换器。
2023-08-08 15:01:30
NOTE
与JMS类似,我们有两个可选方案:●使用RabbitTemplate从队列拉取消息;●将消息推送至带有@RabbitListener注解的方法中。
2023-08-08 15:03:30
NOTE
你可能会注意到,很多方法都接收一个long类型的参数,用来指定接收消息的超时时间。默认情况下,接收消息的超时时间是0毫秒。
2023-08-08 15:05:22
NOTE
通过传入一个超时时间的值,我们就可以让receive()和receiveAndConvert()阻塞,直到消息抵达或者超时。但是,即便设置了非零的超时时间,代码中依然要处理null返回值的场景。
2023-08-08 15:05:35
NOTE
如果你觉得使用这样一个硬编码的数字会让人觉得不舒服,认为更好的方案是创建一个带有@ConfigurationProperties注解的类,并使用Spring Boot的配置属性来设置超时时间,那么在这一点上,我的想法和你一样,只不过Spring Boot已经为我们提供了一个这样的配置属性。想要通过配置来设置超时时间,只需要在调用receive()时移除超时值,并将超时时间设置为spring.rabbitmq.template.receive-timeout属性:
2023-08-08 15:13:17