Spring Boot 构建RESTful Web 服务
前言
Spring Boot 为企业应用程序构建 RESTful Web 服务提供了非常好的支持。 本章将详细介绍如何使用 Spring Boot 构建 RESTful Web 服务。
RESTful 入门
什么是 REST
REST 即表述性状态传递(英文:Representational State Transfer, 简称 REST)是 Roy Thomas Fielding 博士在 2000 年他的博士论文中提出来的 一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸性。
如果一个架构符合 REST 原则,就称它为 RESTful 架构。
产生的背景
随着移动互联网的发展,前端设备层出不穷(手机、平板、桌面电脑…), 必须有一种统一的机制,方便不同的前端设备与后端进行通信,于是 RESTful 诞生了,通过一套统一的接口为 Web,iOS 和 Android 提供服务。
资源(Resources)
所谓"资源",就是网络上的一个实体,或者说是网络上的一 个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个 具体的实体。你可以用一个 URI(统一资源定位符)指向它,每种资源对应一个特定的 URI。要获取这个资源,访问它的 URI 就可以,因此 URI 就成了每一个资源的地址或独一无二的识别符。所谓"上网",就是与互联网上一系列的"资源"互动,调用它的 URI。
表现层(Representation)
1、"资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现层"。
2、比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现;图片可以用 JPG 格式表现,也可以用 PNG 格式表现。
3、URI 只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html" 后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴,而 URI 应该只代表"资源"的位置。它的具体表现形式,应该在 HTTP 请求的头信息 中用 Accept 和 Content-Type 字段指定,这两个字段才是对"表现层"的描述。
状态转化(State Transfer)
1、访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。
2、互联网通信协议 HTTP 协议,是一个无状态协议。这意味着所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。
3、客户端用到的手段,只能是 HTTP 协议。具体来说,就是 HTTP 协议里面,表示操作方式的动词:GET、POST、PUT、PATCH、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源(客户端提供改变后的完整资源),PATCH 用来更新资源(客户端提供改变的属性),DELETE 用来删除资源。
SpringBoot 构建 RESTful Web 服务
1、重要的注解
@RestController 注解:用于定义 RESTful Web 服务。它提供 JSON,XML 和自定义响应。
@RequestMapping 注释:用于定义访问 REST 端点的 Request URI。
@GetMapping 注解:接收和处理 get 方式的请求
@PostMapping 注解:接收和处理 post 方式的请求
@PutMapping 注解:接收和处理 put 方式的请求
@DeleteMapping 注解:接收和处理 delete 方式的请求
@RequestBody 注解:用于定义请求正文内容类型。
@RequestHeader 注解:获取请求头中指定的参数值。
@PathVariable注解:用于定义自定义或动态请求URI。请求URI中的 Path 变量定义为花括号{}。
@RequestParam 注解:用于从请求 URL 读取请求参数。
2、如果编写的是对一个用户的增删改查操作,如下表是一个非 RESTful 和 标准 RESTful 的对比表。
案例
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; @Data @AllArgsConstructor @NoArgsConstructor public class User { private String userId; private String userCode; private String nickName; @JsonFormat(pattern = "yyyy-mm-dd") private Date birthday; }
import cn.wlh.demo.pojo.User; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; /** * restful风格 */ @RestController @RequestMapping("/api") public class UserController { private static Map userMap = new HashMap(); static { userMap.put("1",new User("1","zbt","周伯通",new Date())); userMap.put("2",new User("2","lwt","老顽童",new Date())); userMap.put("3",new User("3","xln","小龙女",new Date())); userMap.put("4",new User("4","yg","杨过",new Date())); } /** * 查询所有 * @return */ @GetMapping("/users") public Map findAllUsers(){ return userMap; } /** * 根据id查询 * @param id * @return */ @GetMapping("/users/{id}") public User findUserById(@PathVariable String id){ return userMap.get(id); } /** * 添加 * @param user * @return */ @PostMapping("/users") public User addUser(@RequestBody User user){ userMap.put(user.getUserId(),user); for (User temp : userMap.values()) { System.out.println("=====添加用户=====" + temp); } return user; } /** * 修改 * @param user * @return */ @PutMapping("/users/{id}") public User modifyUser(@PathVariable String id,@RequestBody User user){ userMap.put(id, user); for (User temp : userMap.values()) { System.out.println("=====用户修改=====" + temp); } return user; } /** * 删除 * @param id * @return */ @DeleteMapping("/users/{id}") public User deleteUser(@PathVariable String id){ User user = userMap.get(id); userMap.remove(id); for (User temp : userMap.values()) { System.out.println("=====用户删除=====" + temp); } return user; } }