#Springboot + Mybatis + Swagger2 构建Restful风格的API接口
1级标题
Springboot + spring data jpa + Swagger2 https://www.jianshu.com/p/85df3247660d
swagger2可以将项目的所有接口在一个UI界面上展示出来,同时表明了这个接口的用途,接口需要的参数是什么类型参数是否必须,输入了参数可以直接测试接口类似postman的功能,会显示接口请求的状态码和返回的数据结构。
优点:
大大减少前后端的沟通
方便查找和测试接口
提高团队的开发效率
方便新人了解项目
1.新建spring boot 项目
2.添加如下依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.fxm.study</groupId>
<artifactId>restful</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>restful</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<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>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<!-- 此配置不可缺,否则mybatis的Mapper.xml将会丢失 -->
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!--指定资源的位置-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
#数据库配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/nobody2?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
新建好mybatis的相关包,dao,service,pojo等,目录如下:
package cn.fxm.study.restful;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("cn.fxm.study.restful.dao")
public class RestfulApplication {
public static void main(String[] args) {
SpringApplication.run(RestfulApplication.class, args);
}
}
3.写配置类
配置类创建一个SwaggerConfiguration配置类,简单解释一下,@Configuration注解让spring来加载配置,@EnableSwagger2开启swagger2。
package cn.fxm.study.restful;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("cn.fxm.study.restful")) //扫描路径
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("springboot利用swagger构建api文档") //页面标题
.description("简单优雅的restful风格") //描述
.termsOfServiceUrl("http://blog.csdn.net/forezp")
.contact("1064794756@qq.com") //联系人
.version("1.0") //版本
.build();
}
}
通过@Configuration注解,表明它是一个配置类,@EnableSwagger2开启swagger2。apiINfo()配置一些基本的信息。apis()指定扫描的包会生成文档。
4.生成文档的注解
还没有写文档的注解前的代码如下:
package cn.fxm.study.restful.controller;
import cn.fxm.study.restful.pojo.Emp;
import cn.fxm.study.restful.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@RequestMapping(value = "/emp")
public class IndexController {
@Autowired
EmpService empService;
@GetMapping(value = "/{id}") //http://localhost:8080/emp/34
public Emp get(@PathVariable(name = "id") Integer id){
Emp emp = empService.selectByPrimaryKey(id);
return emp;
}
@PostMapping(value = "")
public Emp get(@RequestBody Emp newEmp){
int i = empService.insert(newEmp);
Emp emp = null;
log.warn("新增员工的id为:" + newEmp.getEmpno());
if(i>0){
emp = empService.selectByPrimaryKey(newEmp.getEmpno());
}
return emp;
}
@PutMapping(value = "")
public Emp put(@RequestBody Emp newEmp){
int i = empService.updateByPrimaryKeySelective(newEmp);
Emp emp = null;
log.warn("要修改员工的id为:" + newEmp.getEmpno());
if(i>0){
emp = empService.selectByPrimaryKey(newEmp.getEmpno());
}
return emp;
}
@DeleteMapping(value = "/{id}")
public String delete(@PathVariable(name = "id") Integer id){
int i = empService.deleteByPrimaryKey(id);
log.warn("要删除的员工id为:" + id);
String msg = "{\"delete\":\"failed\"}";
if(i>0){
msg = "{\"delete\":\"success\"}";
}
return msg;
}
}
针对当前控制器的增删改查访问方式如下:
post 方式增加一个员工,并将新增的员工的基本信息返回:
get 方式获得一个员工的基本信息:
put方式修改一个员工的基本信息:
delete方式删除一个员工的基本信息:
**为indexcontroller类添加文档注解:(注解的写法参考:**https://msd.misuland.com/pd/3047868153708151502)
package cn.fxm.study.restful.controller;
import cn.fxm.study.restful.pojo.Emp;
import cn.fxm.study.restful.service.EmpService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Api(tags = "员工管理",description = "对emp员工的增删改查操作")
@Slf4j
@RestController
@RequestMapping(value = "/emp")
public class IndexController {
@Autowired
EmpService empService;
@ApiOperation(value="获得指定id的员工", notes="根据id来获取员工对象")
@ApiImplicitParam(dataType = "java.lang.Integer", name = "id",value = "用户id" , paramType = "query")
@GetMapping(value = "/query/") //http://localhost:8080/emp
public Emp get2(@RequestParam(name = "id") Integer id){
Emp emp = empService.selectByPrimaryKey(id);
log.warn("paramType = query 方式");
return emp;
}
@ApiOperation(value="获得指定id的员工", notes="根据id来获取员工对象")
@ApiImplicitParam(dataType = "java.lang.Integer", name = "id",value = "用户id" , paramType = "path")
@GetMapping(value = "/{id}") //http://localhost:8080/emp/34
public Emp get(@PathVariable(name = "id") Integer id){
Emp emp = empService.selectByPrimaryKey(id);
log.warn("paramType = path 方式");
return emp;
}
@ApiOperation(value="添加员工", notes="添加员工信息")
@ApiImplicitParam(name = "newEmp",value = "员工信息", dataType = "Emp")
@PostMapping(value = "")
public Emp get(@Valid @RequestBody Emp newEmp){
int i = empService.insert(newEmp);
Emp emp = null;
log.warn("新增员工的id为:" + newEmp.getEmpno());
if(i>0){
emp = empService.selectByPrimaryKey(newEmp.getEmpno());
}
return emp;
}
@ApiOperation(value="修改员工", notes="修改员工信息")
@ApiImplicitParam(name = "newEmp",value = "员工信息", dataType = "Emp")
@PutMapping(value = "")
public Emp put(@RequestBody Emp newEmp){
int i = empService.updateByPrimaryKeySelective(newEmp);
Emp emp = null;
log.warn("要修改员工的id为:" + newEmp.getEmpno());
if(i>0){
emp = empService.selectByPrimaryKey(newEmp.getEmpno());
}
return emp;
}
@ApiOperation(value="删除指定id的员工", notes="根据id来删除员工信息")
@ApiImplicitParam(name = "id",value = "用户id", dataType = "java.lang.Integer", paramType = "path")
@DeleteMapping(value = "/{id}")
public String delete(@PathVariable(name = "id") Integer id){
int i = empService.deleteByPrimaryKey(id);
log.warn("要删除的员工id为:" + id);
String msg = "{\"delete\":\"failed\"}";
if(i>0){
msg = "{\"delete\":\"success\"}";
}
return msg;
}
}
model类的注解:
package cn.fxm.study.restful.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
@ApiModel(description = "员工对象")
public class Emp {
@ApiModelProperty(notes = "员工编号")
@NotNull(message = "员工编号不能为空")
private Integer empno;
@ApiModelProperty(value = "员工名称")
@NotNull(message = "员工名称不能为空")
private String ename;
@ApiModelProperty(value = "工作名称")
private String job;
@ApiModelProperty(value = "部门编号")
private Integer deptno;
}
完成上述代码后,打包Spring Boot程序并启动,打开浏览器访问:http://localhost:8080/swagger-ui.html,就能看到前文所展示的RESTful API的页面。
另外的快速集成方式:https://www.jianshu.com/p/26772c1267a9
还可以在接口中进行数据校验,在上文中已经在新增员工中对数据进行了校验,其实在更新中还要进一步对emp对象进行校验,所以需要用到spring @Validated 注解开发中使用group分组校验。
由于项目中默认使用了spring-boot-starter-web依赖,在这个依赖中又依赖了 hibernate.validator 所以无需在集成验证jar包了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
新建uitl包,在util包下新建:
package cn.fxm.study.restful.util;
public interface Insert {
}
package cn.fxm.study.restful.util;
public interface Update {
}
在pojo.java中进行如下修改:
package cn.fxm.study.restful.pojo;
import cn.fxm.study.restful.util.Insert;
import cn.fxm.study.restful.util.Update;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
@ApiModel(description = "员工对象")
public class Emp {
@ApiModelProperty(notes = "员工编号")
@NotNull(message = "员工编号不能为空",groups = Update.class)
private Integer empno;
@ApiModelProperty(value = "员工名称")
@NotNull(message = "员工名称不能为空",groups = {Update.class, Insert.class})
private String ename;
@ApiModelProperty(value = "工作名称")
@NotNull(message = "员工工作名称不能为空",groups = Insert.class)
private String job;
@ApiModelProperty(value = "部门编号")
private Integer deptno;
}
控制层:
package cn.fxm.study.restful.controller;
import cn.fxm.study.restful.pojo.Emp;
import cn.fxm.study.restful.service.EmpService;
import cn.fxm.study.restful.util.Insert;
import cn.fxm.study.restful.util.Update;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@Api(tags = "员工管理",description = "对emp员工的增删改查操作")
@Slf4j
@RestController
@RequestMapping(value = "/emp")
public class IndexController {
@Autowired
EmpService empService;
@ApiOperation(value="获得指定id的员工", notes="根据id来获取员工对象")
@ApiImplicitParam(dataType = "java.lang.Integer", name = "id",value = "用户id" , paramType = "query")
@GetMapping(value = "/query/") //http://localhost:8080/emp
public Emp get2(@RequestParam(name = "id") Integer id){
Emp emp = empService.selectByPrimaryKey(id);
log.warn("paramType = query 方式");
return emp;
}
@ApiOperation(value="获得指定id的员工", notes="根据id来获取员工对象")
@ApiImplicitParam(dataType = "java.lang.Integer", name = "id",value = "用户id" , paramType = "path")
@GetMapping(value = "/{id}") //http://localhost:8080/emp/34
public Emp get(@PathVariable(name = "id") Integer id){
Emp emp = empService.selectByPrimaryKey(id);
log.warn("paramType = path 方式");
return emp;
}
@ApiOperation(value="添加员工", notes="添加员工信息")
@ApiImplicitParam(name = "newEmp",value = "员工信息", dataType = "Emp")
@PostMapping(value = "")
public Emp get(@Validated({Insert.class})@RequestBody Emp newEmp){
int i = empService.insert(newEmp);
Emp emp = null;
log.warn("新增员工的id为:" + newEmp.getEmpno());
if(i>0){
emp = empService.selectByPrimaryKey(newEmp.getEmpno());
}
return emp;
}
@ApiOperation(value="修改员工", notes="修改员工信息")
@ApiImplicitParam(name = "newEmp",value = "员工信息", dataType = "Emp")
@PutMapping(value = "")
public Emp put(@Validated({Update.class}) @RequestBody Emp newEmp){
int i = empService.updateByPrimaryKeySelective(newEmp);
Emp emp = null;
log.warn("要修改员工的id为:" + newEmp.getEmpno());
if(i>0){
emp = empService.selectByPrimaryKey(newEmp.getEmpno());
}
return emp;
}
@ApiOperation(value="删除指定id的员工", notes="根据id来删除员工信息")
@ApiImplicitParam(name = "id",value = "用户id", dataType = "java.lang.Integer", paramType = "path")
@DeleteMapping(value = "/{id}")
public String delete(@PathVariable(name = "id") Integer id){
int i = empService.deleteByPrimaryKey(id);
log.warn("要删除的员工id为:" + id);
String msg = "{\"delete\":\"failed\"}";
if(i>0){
msg = "{\"delete\":\"success\"}";
}
return msg;
}
}