《精通SpringMVC4》读书笔记2
第五章、创建RESTful应用
5.1 什么是REST
REST(Representational State Transfer表述性状态转移)是一种架构风格,RESTful Web 服务会天然具备如下的属性。
- 客户端-服务器: UI 是与数据存储分离的。
- 无状态: 每个请求会包含服务器所需的足够信息,无需维护状态就能进行操作。
- 可缓存: 服务器的响应 中包含了足够得信息,客户端能够对数据存储做出合理的决策。
- 统一接口: URL会唯一识别资源,能够通过超链接发现API
- 分层: API的每个资源都提供了合理程度的细节。
5.2 Richardson成熟度模型
描述web API的RESTful程度,这个级别的目的在于通过暴露多个特定的资源,处理应用程序的复杂性。
0级:HTTP
让资源在网络上可以通过HTTP获取即可
1级:资源
REST和资源密切相关,资源是模型中某个元素的唯一标识符。借助HTTP,资源会与一个统一资源标识符URL关联,例如:
- /users 将会包含所有用户的列表;
- /user/42 将会包含特定的用户;
- /user/42/tweets包含了特定用户的所有Tweet 列表。
API 形式的定义完全取决于你,只需记住一条简单的规则:最小惊讶原则。给用户提供所预期的内容,这样你的API 就已经很好了。
2级:HTTP动作
通过HTTP动作识别资源可能的行为。
- GET:在一个特定的URL 上读取数据。
- HEAD:它的行为与GET 相同,但是不包含响应体。在获取资源的元数据(如缓存信息等等)时,这种方式是有用
- DELETE:这将会删除某个资源。
- PUT;这会更新或创建资源。
- POST:这会更新或创建资源
- PATCH:这会部分更新资源。
- OPTIONS:这会返回服务端针对特定资源所支持方法列表。
在这个级别响应有意义的HTTP代码
第三级:超媒体控制
RESTful服务最重要的特性:通过使用超文本连接,可以进行服务的发现。其实就是服务端通过响应头或者响应体告诉客户端可选的功能。例如:
在使用PUT方法创建资源之后,服务端应返回代码为“210 CREATED” 的响应,并在响应头信息中使用Location属性包含新创建资源的URI.
5.3 API版本化
5.4 有用的HTTP代码
- 2XX 所有事情正常运行
- 3XX 重定向
- 4XX 客户端错误
- 5XX 服务端错误
5.5客户端为王
允许第三方客户端 通过REST API来获取搜索结果,搜索结果可以用JSON或者XML来展现。
@RestController 注解是一种快捷方式,它所声明的控制器在返回响应时就如同使用了@ResponseBody注解一样,它告诉Spring将返回类型序列化为合适的格式,默认情况下使用JSON格式
SpringBoot将会使用Jackson将返回结果序列化
5.6 调试RESTful API
调试工具 postman
5.7 自定义JSON输出
SpringBoot所使用的JSON序列化库JackSon默认会将getter方法能访问到的所有属性都序列化,但模型类有些字段不是我们需要的,我们可以再类级别上使用@JsonIgnoreProperties注解,定义想要忽略的一组属性也可以在西安高忽略的属性的get方法上使用@JosnIgnore。
直接序列化模型类不是很好的方案,应该创建用于序列化的新类封装返回结果DTO类
5.9 状态码与异常处理
- 500 Server Error:这表明在处理请求的时候出现了错误。
- 405 Method not Supported:当你在已有的处理器上使用错误的方法时,会出现这个错误。
- 404 Not Found:当处理器不存在时,会出现该错误。
- 400 Bad Request:这表明请求体或参数不能匹配服务器端的预期。
- 200 OK:如果请求处理没有遇到任务错误的话,将会对应该状态。
- Spring MVC 中,有两种方式来返回状态码 在 REST 控制器中,返回ResponseEntity 类。 所抛出的异常由专门的处理器获。
带有状态码的ResponseEntity
@RestControllerAdvice(“com*webcontroller”)
在类级别使用@ExceptionHandler,类似于我们在第4 章中,在上传控制器上处理IOException 的方式;
使用@ControllerAdvice,捕获所有控制器或控制器的一个子集所抛出的全局异常。
第八章
8.3缓存控制
spring的缓存注解基于代理机制,借助代理,能够为带有@Cacheable注解的方法提供缓存功能,使用缓存要求缓存方法的参数和返回值都是可序列化的
8.4.2 分布式缓存,使用redis作为缓存提供者,这样就能够跨多台服务器,实现分布式缓存
8.5 异步方法
8.6ETag:web相应数据的一个散列(hash),并且会在头信息中进行发送。
- 我们在服务器端使用了缓存之后,当用户刷新页面之后会直接从缓存中获取数据。但是即使结果没有发生变化,结果本身还是会多次发送给客户端,这样会浪费带宽。
- 客户端可以记住资源的ETag,并且通过If-None-Match头信息将最新的已知版本发送给服务器。如何在这段时间请求没有发生变化,服务器可以回应304 Not Modified。如果服务器响应304 Not Modified就从本地缓存中获取内容来处理响应。
- ETag 还有其他的用途,例如事务的乐观锁(它能够让你在任意时间都知道客户端该使用哪个版本的对象)。在发送数据之前进行散列操作,这会给服务端带来额外的工作,但这种方式会节省带宽。
8.7 WebSocket
Spring为WebSocket提供了良好的支持。WebSocket协议允许客户端维持与服务器的长连接。数据可以通过WebSocket在两个端点之间进行双向传输,因此消费数据的一方能够实时的获取数据。
websocket
HTTP的长连接与短连接:
https://www.cnblogs.com/miaozhihang/p/9518584.html
什么是http协议?
- HTTP是一个应用层协议,无状态的,端口号为80。主要的版本有1.0/1.1/2.0. HTTP/1.*
- 一次请求-响应,建立一个连接,用完关闭; HTTP/1.1
- 串行化单线程处理,但一个网页打开完成后,客户端和服务器之间建立的用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。也就是说,在这样一个HTTP连接中,可以发送多个Request,接收多个Response。但是Request和Response永远是相对应的,也就是说一个request只能有一个response。并且这个response也是被动的,不能主动发起。只有上一个请求完后,下一个才能响应。一旦有任务处理超时等,后续任务只能被阻塞(线头阻塞);
- HTTP/2 并行执行。某任务耗时严重,不会影响到任务正常执行
什么是WebSocket?
Websocket其实是基于HTTP协议的一个新的协议,是HTTP协议上的一种补充,但是不等于http协议的长连接(有交集,但是基本没有关系:Websocket 属于HTML5新特性,而http协议和HTML本身没有直接关系)。
Websocket本质上是一个基于tcp的,先通过HTTP/HTTPS协议发起一条特殊的http请求进行握手后创建一个用于交换数据的TCP连接。
WebSocket解决的http的几项难题:
- 被动性
当服务器完成协议升级后(即由 HTTP 升级为 Websocket),服务端就可以主动推送信息给客户端;只需要经过一次HTTP请求,就可以做到源源不断的信息传送。 - 服务器端的资源消耗
long poll 和 ajax轮询 对服务器资源有很大的消耗:ajax轮询需要服务器有很快的资源处理速度;long poll 采用阻塞模型,需要有很高的并发,占用服务器资源空间。
而Websocket建立后,可以直接建立持久连接,有信息的时候由服务端主动进行信息传送。 - 处理速度慢
HTTP协议是无状态的,每建立一次http协议,就要重新发送鉴别信息告诉服务器你是谁,因此会消耗多余无用的传输和处理的时间;Websocket只需要一次HTTP握手,就可以保持通讯状态,直到关闭请求。解决了反复解析HTTP协议,查看identity info的问题。
服务器与客户端之间交换的头信息很小。