《Spring实战》读书笔记--使用SpringMVC构建REST API

《Spring实战》读书笔记--使用SpringMVC构建REST API

1. REST介绍



REST(Representational State Transfer):表述性状态转移,是基于HTTP、URI、MIME(HTML、JSON等)协议的Web软件架构。它不同于SOAP Web服务(RPC)关注处理,面向行为,其更关注要处理的数据,面向资源。

1.1 《Spring实战》中是这样描述REST的

为了理解REST是什么,我们将它的首字母缩写才拆分为不同的构成部分:

  • 表述性(Representational):REST资源实际上可以用各种形式来进行表述,包括XML、HTML、JSON及HTML---最适合资源使用者的任意形式。
  • 状态(State):当使用REST的时候,我们更关注资源的状态而不是对资源采取的行为。
  • 转移(Transfer):REST涉及转移资源数据,它以某种表述性从一个应用转移到另一个应用。

在REST中,资源通过URL进行识别和定位。REST中会有行为,它们是通过HTTP方法来进行定义的。这些HTTP方法通常匹配如下CURD动作:

  • Create: POST
  • Read: GET
  • Update: PUT或PATCH
  • Delete: DELETE

我是萌萌的分割线

1.2 wiki是这样描述REST的

  • 资源是由URI来指定。
  • 对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
  • 通过操作资源的表现形式来操作资源。
  • 资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。

RESTful API:符合REST设计风格的Web API,它从以下三个方面资源进行定义的:

  • 直观简短的资源地址:URI,比如:http://example.com/resources/
  • 传输的资源:Web服务接受与返回的互联网媒体类型,比如:JSON,XML,YAML,HTML等。
  • 对资源的操作:Web服务在该资源上所支持的一系列请求方法(比如:POST,GET,PUT或DELETE)。

HTTP请求方法在RESTful API中的典型应用:

资源 GET PUT POST DELETE
一组资源的URI,比如http://example.com/resources/ 列出URI,以及该资源组中每个资源的详细信息(后者可选)。 使用给定的一组资源替换当前整组资源。 在本组资源中创建/追加一个新的资源。该操作往往返回新资源的URL。 删除整组资源。
单个资源的URI,比如http://example.com/resources/142 获取指定的资源的详细信息,格式可以自选一个合适的网络媒体类型(比如:XML、JSON等) 替换/创建指定的资源。并将其追加到相应的资源组中。 把指定的资源当做一个资源组,并在其下创建/追加一个新的元素,使其隶属于当前资源。 删除指定的元素。

实现举例:

列出所有物品:GET http://www.store.com/products

呈现某一件商品: GET http://www.store.com/product/12345

呈现一些商品(过滤规则):GET http://www.store.com/product/1022?limit=10(id为1022后的10件商品)

下单购买:

POST http://www.store.com/order <purchase-order> <item> ... </item> </purchase-order>

1.3 实现网站(自己找了几个网站看了看,有几个网站个人觉得API挺符合RESTful API):

小米官网:看了几家购物网站,就觉得小米官网除了登录(估计安全原因),其它的设计挺符合RESTful API

落网:一家音乐网站,其推荐的小众音乐挺不错的。因为其功能较为简单,所以其API看起来挺简洁的,一眼看上去就符合RESTful API

我是萌萌的分割线

1.4 私以为

其实自己看了后,感觉不是太懂,模模糊糊的。下面简单说点自己的理解吧:

  • 基于RESTful API 能够前后端分离,前端不管是web浏览器还是移动终端只要访问响应的API,就能够得到相应的资源。
  • RPC(远程过程化调度)感觉就是基于服务的,更看重行为,一般直接从service层就暴露接口了。而REST上面所说是基于资源的,其一般从web层暴露接口(RESTful API),它更看重对资源的行为(通过HTTP请求方法表现),也就是说我们冲RESTful API中看不出行为来,仅仅能够看出操作资源。

1.5 设计好的RESTful API接口

RESTful API的设计原则

2.SpringMVC中的REST



2.1 大体结构

在一般的SpringMVC框架中处理流程如下:

当HTTP请求到达DispatcherServlet时,DispatcherServlet通过handlerMapping找到该URL对于的Controller后,DispatcherServlet会把HttpServletRequest转发给Controller处理(SpringMVC在这里做了许多的改进)。Controller处理完后会把Model and View传给DispatcherServlet,其会通过ViewResolver找到物理视图,然后把Model发给该视图中进行渲染,最后视图会响应HTTP请求,发送响应的数据。

REST在SpringMVC框架中处理流程如下:

当HTTP请求到达DispatcherServlet时,DispatcherServlet通过handlerMapping找到该URL对于的Controller后,DispatcherServlet会把HttpServletRequest转发给Controller处理(SpringMVC在这里做了许多的改进)在这里时,SpringMVC会通过消息转化器(Message Conversion)@RequestBody、@RequestMapping、@PathVariable接受响应的资源,GET、POST等方法标注行为。然后Controller调用service处理相关资源行为,最后在通过Message Conversion(@ResponseBody)返回数据。

2.2 支持的构件

SpringMVC在Controller中有许多的构件支持REST:

  • HTTP方法构件。在@RequestMapping()参数中可以通过method=RequestMethod.GET 来指定响应的方法。
  • 在@RequestMapping()参数中可以通过produces={"application/json;charset=UTF-8"} 来响应HTTP请求中的Accept字段,如果Request中Accept不支持该字段,则会返回HTTP 406 (Not Acceptable)响应。
  • 在@RequestMapping()参数中可以通过consumes={"application/json"} 来响应请求中的Content-Type字段,如果Request中Content-Type不支持该字段,则会返回HTTP 415 ( Unsupported Media Type)响应。
  • 获得数据构件。@ReqeustParam()可以获取Query String Parameters、Form Data等,@PathVariable()可以获取路径变量。
  • 消息转换器(Message Conversion)转换消息。通过@RequestBody()可以把请求数据通过相关类库(如Jackson)转换Java对象,通过@ResponseBody()可以把Java对象数据通过相关类库(如Jackson)转换为Json对象。
  • 可以在类级别使用@RestController。该类的所有方法都会默认的使用消息转化器,相当于每个方法都有@ResponseBody()注解。

2.3 Spring使用

导入Jackson

1 <dependency>
2     <groupId>com.fasterxml.jackson.core</groupId>
3     <artifactId>jackson-databind</artifactId>
4     <version>2.4.3</version>
5 </dependency>

JS

 1 function login(){
 2     var username = $(‘#username‘).val();
 3     var password = $(‘#password‘).val();
 4     var message = $(‘#message‘);
 5     if(username.length<6 || password.length <6){
 6         message.hide().html(‘用户或密码位数小于6位‘).show();
 7     }else{
 8         $.ajax({
 9             url : "/springMVC/hello",
10             type : "POST",
11             dataType : "text",
12             timeout : 10000,
13             data : {"username":username,"password":password},
14             success : function(result){
15                 console.log(result);
16             }
17         });
18     }
19 }

Controller

 1 @Controller
 2 @RequestMapping(value="/springMVC")
 3 public class UserController {
 4     @RequestMapping(value="/login", method=RequestMethod.GET)
 5     public String login() {
 6     return "login";
 7     }
 8
 9     @RequestMapping(value="/hello")
10     @ResponseBody
11     public User hello(@RequestParam(value="username") String username,
12         @RequestParam(value="username")String password) {
13         System.out.println(username + "\t" + password);
14         User user = new User(5,username);
15         return user;
16     }
17 }

HTTP Request

 1 POST /springMVC/hello HTTP/1.1
 2 Accept:text/plain, */*; q=0.01
 3 Accept-Encoding:gzip, deflate, br
 4 Accept-Language:zh-CN,zh;q=0.8
 5 Connection:keep-alive
 6 Content-Length:31
 7 Content-Type:application/x-www-form-urlencoded; charset=UTF-8
 8 Cookie:JSESSIONID=1mnbs1bxxlxvblq759pgltl8q
 9 Host:localhost:8080
10 Origin:http://localhost:8080
11 Referer:http://localhost:8080/springMVC/login
12 User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36
13 X-Requested-With:XMLHttpRequest
14 Form Data
15 view parsed
16
17 username=132456&password=123456

HTTP Response

1 HTTP/1.1 200 OK
2 Content-Type:application/json;charset=UTF-8
3 Date:Wed, 12 Apr 2017 15:27:27 GMT
4 Server:Jetty(8.1.14.v20131031)
5 Transfer-Encoding:chunked
6
7 {"id":5,"name":"132456"}

3.References

https://zh.wikipedia.org/wiki/REST

时间: 2024-10-17 23:00:49

《Spring实战》读书笔记--使用SpringMVC构建REST API的相关文章

Spring实战读书笔记(1)

Spring的根本使命是? 简化Java开发 为了降低Java开发的复杂性,Spring采取了哪4种关键策略? 1.基于POJO的轻量级和最小侵入性编程 2.通过依赖注入和面向接口实现松耦合 3.基于切面和惯例进行声明式编程 4.通过切面和模板减少样板式代码 依赖注入与AOP编程 1.如果想对依赖注入有更多的认识,推荐阅读Dhanji R. Prasanna的<Dependency Injection> 2.依赖注入让相互协作的软件组件保持松散耦合,而AOP编程允许你把遍布应用各处的功能分离出

R实战读书笔记四

第三章 图形入门 本章概要 1 创建和保存图形 2 定义符号.线.颜色和坐标轴 3 文本标注 4 掌控图形维数 5 多幅图合在一起 本章所介绍内容概括如下. 一图胜千字,人们从视觉层更易获取和理解信息. 图形工作 R具有非常强大的绘图功能,看下面代码. > attach(mtcars) > plot(wt, mpg) > abline(lm(mpg~wt)) > title("Regression of MPG on Weight") > detach(m

JAVA并发编程实战 读书笔记(二)对象的共享

<java并发编程实战>读书摘要 birdhack 2015年1月2日 对象的共享 JAVA并发编程实战读书笔记 我们已经知道了同步代码块和同步方法可以确保以原子的方式执行操作,但一种常见的误解是,认为关键之synchronized只能用于实现原子性或者确定临界区.同步还有另一个重要的方面:内存可见性. 1.可见性 为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制. 在没有同步的情况下,编译器.处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整.在缺乏足够同步的多线程程

spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定

本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Provider提供两个功能对象的创建,依赖关系的管理. 只是,IoC容器这个词中,我们还得关注容器二字.它还包括了一些别的功能,例如以下图 Spring提供了两种类型的容器,各自是BeanFactory与ApplicationContext. 它们的差别在于: BeanFactory:对于它所管理的bean,採

spring揭秘 读书笔记 一

本文是王福强所著<<spring揭秘>>一书的读书笔记 ioc的基本概念 一个例子 我们看下面这个类,getAndPersistNews方法干了四件事 1 通过newsListener获得所有的新闻id; 2 通过newsListener,用新闻id获得新闻实体 3 用newPersistener存储新闻实体 4 再使用newsListener发布新闻 public class FXNewsProvider { private IFXNewsListener newsListene

spring揭秘 读书笔记 二

本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,而且IoC Service Provider提供两个功能对象的创建,依赖关系的管理. 不过,IoC容器这个词中,我们还得关注容器二字.它还包含了一些别的功能,如下图 Spring提供了两种类型的容器,分别是BeanFactory与ApplicationContext. 它们的区别在于: BeanFactory:对于它所管理的bean,采取的

Hadoop读书笔记(三)Java API操作HDFS

Hadoop读书笔记(一)Hadoop介绍:http://blog.csdn.net/caicongyang/article/details/39898629 Hadoop读书笔记(二)HDFS的shell操作:http://blog.csdn.net/caicongyang/article/details/41253927 JAVA URL 操作HDFS OperateByURL.java package hdfs; import java.io.InputStream; import jav

《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&amp;并发容器类&amp;同步工具类,消费者模式

上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Hashtable,此外还包括在JDK1.2中添加的一些功能相似的类,这些同步的封装器类由Collections.synchronizedXxx等工厂方法创建的.这些类实现线程安全的方式是:将他们的状态封装起来,并对每个共有方法都进行同步,使得每次只能有一个线程能访问容器的状态. 关于java中的Vect

Maven实战读书笔记(六):Maven灵活构建

Maven为了支持构建的灵活性,内置了3大特性,即:属性.Profile和资源过滤. 6.1 Maven属性 Maven的属性与Java代码的常量有异曲同工之妙,都是为了消除重复,对相关内容进行统一管理并且可以减少日后升级版本的工作量,降低错误发生的概率. 在POM文件中,可以通过${属性名称}的方式来引用属性. 在Maven中,存在6类属性,分别为: 1) 内置属性,主要有两个,分别为:${basedir}表示项目根目录,即POM文件所在的目录.${version}表示项目的版本. 2) PO