Spring 5.0版本全家桶四

Web 开发进阶

设计好的 RESTful Web Service

Roy Thomas Fielding:REST提供了⼀组架构约束,当作为一个整体来应⽤时,强调组件交互的可伸缩性、接⼝的通用性、组件的独⽴部署、以及用来减少交互延迟、增强安全性、封装遗留系统的中间组件。

Richardson 成熟度模型

Richardson使用三个因素来决定服务的成熟度,即URI,HTTP方法和HATEOAS(超媒体)。服务越多采用这些技术 - 应该考虑更成熟。
Spring 5.0版本全家桶四

Level 0

成熟度的零级别不使用任何URI,HTTP方法和HATEOAS功能。就是与这三个因素不搭边。它只是利用了HTTP通道,没有利用HTTP的其他特性。这些服务具有单个URI并使用单个HTTP方法(通常为POST)。

例如,大多数基于Web服务(WS - *)的服务使用单个URI来标识端点,使用HTTP POST来传输基于SOAP的有效负载,从而有效地忽略其余的HTTP谓词。
类似地,基于XML-RPC的服务以普通旧XML(POX)的形式发送数据。这些是使用单个POST方法构建SOA应用程序并使用XML在服务之间进行通信的最原始方式。

Level 1

成熟度的第一级使用 URI。这些服务使用许多URI但只有一个HTTP动词 - 通常是HTTP POST。它们为Universe中的每个资源提供URI。每个资源都由唯一的URI单独标识。

Level 2

成熟度的第二级使用 URI,HTTP方法。二级服务托管了许多URI可寻址资源。此类服务支持每个公开资源上的几个HTTP谓词 - 创建,读取,更新和删除(CRUD)服务。这里,通常代表业务实体的资源状态可以通过网络进行操作。

级别2是REST原则的良好用例,它主张基于HTTP请求方法使用不同的动词,并且系统可以具有多个资源。

Level 3

成熟度的第三级使用所有三个,即URI,HTTP和HATEOAS。这是Richardson模型中最成熟的一个层次,它鼓励容易发现,并且通过使用HATEOAS可以很容易地使回答变得不言自明。该服务通过一系列资源引导消费者,从而导致应用程序状态转换。

如何实现 Restful Web Service

• 识别资源
• 选择合适的资源粒度
• 设计 URI
• 选择合适的 HTTP ⽅方法和返回码
• 设计资源的表述

识别资源

• 找到领域名词
(1)能⽤用 CRUD 操作的名词
• 将资源组织为集合(即集合资源)
• 将资源合并为复合资源
• 计算或处理理函数

资源的粒度

  1. 站在服务端的⻆角度,要考虑
    • ⽹网络效率
    • 表述的多少
    • 客户端的易易⽤用程度
  2. 站在客户端的⻆角度,要考虑
    • 可缓存性
    • 修改频率
    • 可变性

构建更更好的 URI

• 使⽤用域及⼦子域对资源进⾏行行合理理的分组或划分
• 在 URI 的路路径部分使⽤用斜杠分隔符 ( / ) 来表示资源之间的层次关系
• 在 URI 的路路径部分使⽤用逗号 ( , ) 和分号 ( ; ) 来表示⾮非层次元素
• 使⽤用连字符 ( - ) 和下划线 ( _ ) 来改善⻓长路路径中名称的可读性
• 在 URI 的查询部分使⽤用“与”符号 ( & ) 来分隔参数
• 在 URI 中避免出现⽂文件扩展名 ( 例例如 .php,.aspx 和 .jsp (有人用开发的asp改用jsp后缀欺骗黑客,其实这是没用的))

认识 HTTP 方法

Spring 5.0版本全家桶四

URI 与 HTTP 方法的组合

Spring 5.0版本全家桶四

认识 HTTP 状态码

Spring 5.0版本全家桶四

选择合适的表述

JSON
• MappingJackson2HttpMessageConverter
• GsonHttpMessageConverter
• JsonbHttpMessageConverter
XML
• MappingJackson2XmlHttpMessageConverter
• Jaxb2RootElementHttpMessageConverter
HTML
ProtoBuf
• ProtobufHttpMessageConverter

什么是 HATEOAS

什么是 HATEOAS

Richardson 成熟度模型
• Level 3 - Hypermedia Controls
HATEOAS
• Hybermedia As The Engine Of Application State
• REST 统⼀一接⼝口的必要组成部分

HATEOAS v.s. WSDL

HATEOAS
• 表述中的超链接会提供服务所需的各种 REST 接⼝口信息
• ⽆无需事先约定如何访问服务
传统的服务契约
• 必须事先约定服务的地址与格式

HATEOAS示例

Spring 5.0版本全家桶四

常用的超链接类型

Spring 5.0版本全家桶四

使用 Spring Data REST 实现简单的超媒体服务

认识 HAL

HAL
• Hypertext Application Language
• HAL 是⼀一种简单的格式,为 API 中的资源提供简单⼀一致的链接
HAL 模型
• 链接
• 内嵌资源
• 状态

Spring Data REST

Spring Boot 依赖
• spring-boot-starter-data-rest
常⽤用注解与类
• @RepositoryRestResource
• Resource
• PagedResource

如何访问 HATEOAS 服务

配置 Jackson JSON
• 注册 HAL ⽀支持
操作超链接
• 找到需要的 Link
• 访问超链接

分布式环境中如何解决 Session 的问题

常见的会话解决方案

• 粘性会话 Sticky Session
• 会话复制 Session Replication(网络交互量大,不推荐使用)
• 集中会话 Centralized Session

认识 Spring Session

Spring Session
• 简化集群中的⽤用户会话管理理
• 无需绑定容器器特定解决⽅方案
支持的存储
• Redis
• MongoDB
• JDBC
• Hazelcast

实现原理

定制 HttpSession
• 通过定制的 HttpServletRequest 返回定制的 HttpSession
• SessionRepositoryRequestWrapper
• SessionRepositoryFilter
• DelegatingFilterProxy

基于 Redis 的 HttpSession

引⼊入依赖
• spring-session-data-redis
基本配置
• @EnableRedisHttpSession
• 提供 RedisConnectionFactory
• 实现 AbstractHttpSessionApplicationInitializer
(1)配置 DelegatingFilterProxy

Spring Boot 对 Spring Session 的支持

application.properties
• spring.session.store-type=redis
• spring.session.timeout=
(1)server.servlet.session.timeout=
• spring.session.redis.flush-mode=on-save
• spring.session.redis.namespace=spring:session

使用 WebFlux 代替 Spring MVC

认识 WebFlux

什什是 WebFlux
• 用于构建基于 Reactive 技术栈之上的 Web 应用程序
• 基于 Reactive Streams API ,运⾏行行在非阻塞服务器器上
为什么会有 WebFlux
• 对于非阻塞 Web 应用的需要
• 函数式编程
关于 WebFlux 的性能
• 请求的耗时并不不会有很⼤大的改善
• 仅需少量量固定数量量的线程和较少的内存即可实现扩展

WebMVC v.s. WebFlux

• 已有 Spring MVC 应⽤用,运行行正常,就别改了
• 依赖了大量量阻塞式持久化 API 和网络 API,建议使用 Spring MVC,如果使用MySQL,就使用Spring MVC。
• 已经使用了非阻塞技术栈(比如redis,mongodb),可以考虑使用 WebFlux
• 想要使用 Java 8 Lambda 结合轻量量级函数式框架,可以考虑 WebFlux

WebFlux 中的编程模型

两种编程模型
• 基于注解的控制器器
• 函数式 Endpoints

基于注解的控制器

常用注解
• @Controller
• @RequestMapping 及其等价注解
• @RequestBody / @ResponseBody
返回值
• Mono / Flux