REST 即表现层状态转换(REST,英文:Representational State Transfer). 适合终端到 Server 的调用。
1 .REST 概述
资源 (Resources )
资源就是网络上的一个具体的信息。 可以使用 URI 来映射该资源,因此 URI 是描述唯一资源的标识符。表现层 (Representational )
资源是一种信息的载体,资源可以有多种表现形式。可以使用 请求头来表示,通常使用的是 后缀来区分。状态转化( State Transfer )
访问资源的过程中,涉及数据状态的变化,通过 HTTP 协议中的请求方法 (GET/POST/PUT/DELETE/PATCH) 来定义操作数据状态的转化
HTTP 请求方式 | 含义 |
---|---|
POST | 增加资源 |
PUT | 更改资源,客户端提供需要提供完整的资源属性 |
GET | 查询资源 |
PATCH | 更新资源,客户端提供仅需要的资源属性 |
DELETE | 删除资源 |
HEAD | 类似 GET ,但仅仅只有 HTTP 头信息,头信息包含了需要查找的信息,一般为该资源的元信息,如资源是否存在,长度等 |
OPTIONS | 用于获取 URI 所支持的方法,响应信息会在 HTTP 头中包含一个名为 "Allow" 的头。值是支持的方法,如 GET / POST |
2. Spring Boot 集成 REST 应用开发
- pom 文件配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.zj.sp.rest</groupId>
<artifactId>sp-zj-rest-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>sp-zj-rest-demo</name>
<description></description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- REST 接口开发
package org.zj.sp.rest.spzjrestdemo.user.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.zj.sp.rest.spzjrestdemo.user.model.UserModel;
import org.zj.sp.rest.spzjrestdemo.user.repository.UserRepository;
@RestController
@RequestMapping(path="/api/v1/user/")
public class UserApiController {
private static final Logger logger = LoggerFactory.getLogger(UserApiController.class);
@Autowired
UserRepository userRepository;
/**
* 查询用户列表, 返回 JSON 数据
*/
@GetMapping
public List<UserModel> getUsers(){
return userRepository.findAll();
}
/**
* 按 id 查询用户, 返回 JSON 数据
*/
@GetMapping("{id}")
public UserModel getUser(@PathVariable("id") Long id) {
logger.info("=================" + id);
return userRepository.getOne(id);
}
/**
* 新增用户
*/
@PostMapping(consumes=MediaType.APPLICATION_JSON_UTF8_VALUE)
public void addUser(@RequestBody UserModel model) {
logger.info(model.toString());
userRepository.save(model);
}
/**
* 修改用户
*/
@PutMapping
public void modifyUser(@RequestBody UserModel model) {
userRepository.save(model);
}
@DeleteMapping("{id}")
public void deleteUser(@PathVariable("id") Long id) {
userRepository.deleteById(id);
}
}
- 配置文件
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://192.168.1.6:3306/testdb?useUnicode=true&characterEncoding=utf8&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.show-sql=true
logging.level.root=error
logging.level.org.zj=debug
-
测试结果
3. Swagger UI
Swagger UI 是 REST 接口的一个工具,可以使用Swagger UI 来描述和规范接口
- pom 配置 Swagger UI
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
- javaConfig 配置 Swagger
@Bean
public Docket alipayApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("用户API接口文档")
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("org.zj.sp.rest.spzjrestdemo.user.controller"))
.paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("用户服务")
.description("用户服务接口")
.termsOfServiceUrl("https://www.jianshu.com/u/d775c518e5ba")
.contact(new Contact("联系方式 ", "https://www.jianshu.com/u/d775c518e5ba", "93414020@qq.com"))
.version("1.0").build();
}
- 接口 Swagger 注解配置
package org.zj.sp.rest.spzjrestdemo.user.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.zj.sp.rest.spzjrestdemo.user.model.UserModel;
import org.zj.sp.rest.spzjrestdemo.user.repository.UserRepository;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
@RestController
@RequestMapping(path="/api/v1/user/")
@Api(tags="用户接口")
public class UserApiController {
private static final Logger logger = LoggerFactory.getLogger(UserApiController.class);
@Autowired
UserRepository userRepository;
/**
* 查询用户列表, 返回 JSON 数据
*/
@GetMapping
@ApiOperation(value="查询用户列表")
public List<UserModel> getUsers(){
return userRepository.findAll();
}
/**
* 按 id 查询用户, 返回 JSON 数据
*/
@GetMapping("{id}")
@ApiOperation(value="通过id 查询用户")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long")
public UserModel getUser(@PathVariable("id") Long id) {
logger.info("=================" + id);
return userRepository.getOne(id);
}
/**
* 新增用户
*/
@PostMapping(consumes=MediaType.APPLICATION_JSON_UTF8_VALUE)
@ApiOperation(value="新增用户")
@ApiImplicitParam(name = "model", value = "用户详细实体UserModel", required = true, dataType = "UserModel")
public void addUser(@RequestBody UserModel model) {
logger.info(model.toString());
userRepository.save(model);
}
/**
* 修改用户
*/
@PutMapping
@ApiOperation(value="更新用户")
@ApiImplicitParam(name = "model", value = "用户详细实体UserModel", required = true, dataType = "UserModel")
public void modifyUser(@RequestBody UserModel model) {
userRepository.save(model);
}
@DeleteMapping("{id}")
@ApiOperation(value="通过id 删除用户")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long")
public void deleteUser(@PathVariable("id") Long id) {
userRepository.deleteById(id);
}
}
- swagger 常用注解
@Api:用在类上,说明该类的作用
@ApiOperation:用在方法上,说明方法的作用
@ApiImplicitParams:用在方法上包含一组参数说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
paramType:参数放在哪个地方
header–>请求参数的获取:@RequestHeader
query–>请求参数的获取:@RequestParam
path(用于restful接口)–>请求参数的获取:@PathVariable
body(不常用)
form(不常用)
name:参数名
dataType:参数类型
required:参数是否必须传
value:参数的意思
defaultValue:参数的默认值
@ApiResponses:用于表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:数字,例如400
message:信息,例如”请求参数没填好”
response:抛出异常的类
@ApiModel:描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)
@ApiModelProperty:描述一个model的属性
-
swagger 测试图