一、简介

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新 。接口的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。

我们的RESTful API就有可能要面对多个开发人员或多个开发团队:IOS开发、Android开发、Web开发等。为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题:

  1. 由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳;
  2. 随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象;

而swagger完美的解决了上面的几个问题,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能 来调试每个RESTful API。

二、添加Swagger2依赖

  1. <dependency>
  2. <groupId>io.springfox</groupId>
  3. <artifactId>springfox-swagger2</artifactId>
  4. <version>2.6.1</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>io.springfox</groupId>
  8. <artifactId>springfox-swagger-ui</artifactId>
  9. <version>2.6.1</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.fasterxml.jackson.core</groupId>
  13. <artifactId>jackson-core</artifactId>
  14. <version>2.6.5</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>com.fasterxml.jackson.core</groupId>
  18. <artifactId>jackson-databind</artifactId>
  19. <version>2.6.5</version>
  20. </dependency>
  21. <dependency>
  22. <groupId>com.fasterxml.jackson.core</groupId>
  23. <artifactId>jackson-annotations</artifactId>
  24. <version>2.6.5</version>
  25. </dependency>

三、创建Swagger2配置类

  1. package com.xia.common.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  5. import io.swagger.annotations.ApiOperation;
  6. import springfox.documentation.builders.ApiInfoBuilder;
  7. import springfox.documentation.builders.PathSelectors;
  8. import springfox.documentation.builders.RequestHandlerSelectors;
  9. import springfox.documentation.service.ApiInfo;
  10. import springfox.documentation.spi.DocumentationType;
  11. import springfox.documentation.spring.web.plugins.Docket;
  12. import springfox.documentation.swagger2.annotations.EnableSwagger2;
  13. /**
    • 类描述:配置swagger2信息
    • 创建人:XiaChengwei
    • 创建时间:2017年7月28日 上午10:03:29
    • @version 1.0
    • */
    • @Configuration //让Spring来加载该类配置
    • @EnableWebMvc //启用Mvc,非springboot框架需要引入注解@EnableWebMvc
    • @EnableSwagger2 //启用Swagger2
    • public class Swagger2Config {
    • @Bean
    • public Docket createRestApi() {
    • return new Docket(DocumentationType.SWAGGER_2)
    • .apiInfo(apiInfo()).select()
    • //扫描指定包中的swagger注解
    • //.apis(RequestHandlerSelectors.basePackage("com.xia.controller"))
    • //扫描所有有注解的api,用这种方式更灵活
    • .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
    • .paths(PathSelectors.any())
    • .build();
    • }
    • private ApiInfo apiInfo() {
    • return new ApiInfoBuilder()
    • .title("基础平台 RESTful APIs")
    • .description("基础平台 RESTful 风格的接口文档,内容详细,极大的减少了前后端的沟通成本,同时确保代码与文档保持高度一致,极大的减少维护文档的时间。")
    • .termsOfServiceUrl("http://xiachengwei5.coding.me")
    • .contact("Xia")
    • .version("1.0.0")
    • .build();
    • }
    • }

四、编写swagger注解

实体类:

  1. package com.xia.model;
  2. import java.util.Date;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import com.fasterxml.jackson.annotation.JsonFormat;
  5. import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  6. import com.fasterxml.jackson.annotation.JsonInclude;
  7. import io.swagger.annotations.ApiModel;
  8. import io.swagger.annotations.ApiModelProperty;
  9. /**
    • 人员信息表
    • 注解:@ApiModel 和 @ApiModelProperty 用于在通过对象接收参数时在API文档中显示字段的说明
    • 注解:@DateTimeFormat 和 @JsonFormat 用于在接收和返回日期格式时将其格式化
    • 实体类对应的数据表为: user_info
    • @author XiaChengwei
    • @date: 2017-07-14 16:45:29
    • */
    • @JsonInclude(JsonInclude.Include.NON_NULL)
    • @JsonIgnoreProperties({ "handler","hibernateLazyInitializer" })
    • @ApiModel(value ="UserInfo")
    • public class UserInfo {
    • @ApiModelProperty(value = "ID")
    • private Integer id;
    • @ApiModelProperty(value = "用户登录账号", required = true)
    • private String userNo;
    • @ApiModelProperty(value = "姓名", required = true)
    • private String userName;
    • @ApiModelProperty(value = "姓名拼音")
    • private String spellName;
    • @ApiModelProperty(value = "密码", required = true)
    • private String password;
    • @ApiModelProperty(value = "手机号", required = true)
    • private String userPhone;
    • @ApiModelProperty(value = "性别")
    • private Integer userGender;
    • @ApiModelProperty(value = "记录创建时间")
    • @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    • private Date createTime;
    • @ApiModelProperty(value = "记录修改时间")
    • @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    • private Date updateTime;
    • public Integer getId() {
    • return id;
    • }
    • public void setId(Integer id) {
    • this.id = id;
    • }
    • public String getUserNo() {
    • return userNo;
    • }
    • public void setUserNo(String userNo) {
    • this.userNo = userNo == null ? null : userNo.trim();
    • }
    • public String getUserName() {
    • return userName;
    • }
    • public void setUserName(String userName) {
    • this.userName = userName == null ? null : userName.trim();
    • }
    • public String getSpellName() {
    • return spellName;
    • }
    • public void setSpellName(String spellName) {
    • this.spellName = spellName;
    • }
    • public String getPassword() {
    • return password;
    • }
    • public void setPassword(String password) {
    • this.password = password == null ? null : password.trim();
    • }
    • public String getUserPhone() {
    • return userPhone;
    • }
    • public void setUserPhone(String userPhone) {
    • this.userPhone = userPhone == null ? null : userPhone.trim();
    • }
    • public Integer getUserGender() {
    • return userGender;
    • }
    • public void setUserGender(Integer userGender) {
    • this.userGender = userGender;
    • }
    • @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    • public Date getCreateTime() {
    • return createTime;
    • }
    • public void setCreateTime(Date createTime) {
    • this.createTime = createTime;
    • }
    • @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    • public Date getUpdateTime() {
    • return updateTime;
    • }
    • public void setUpdateTime(Date updateTime) {
    • this.updateTime = updateTime;
    • }
    • @Override
    • public String toString() {
    • StringBuilder sb = new StringBuilder();
    • sb.append(getClass().getSimpleName());
    • sb.append(" [");
    • sb.append("Hash = ").append(hashCode());
    • sb.append(", id=").append(id);
    • sb.append(", userNo=").append(userNo);
    • sb.append(", userName=").append(userName);
    • sb.append(", spellName=").append(spellName);
    • sb.append(", password=").append(password);
    • sb.append(", userPhone=").append(userPhone);
    • sb.append(", userGender=").append(userGender);
    • sb.append(", createTime=").append(createTime);
    • sb.append(", updateTime=").append(updateTime);
    • sb.append("]");
    • return sb.toString();
    • }
    • }

控制类:

  1. package com.infore.controller;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RequestMethod;
  4. import org.springframework.web.bind.annotation.ResponseBody;
  5. import org.springframework.web.bind.annotation.RestController;
  6. import com.github.pagehelper.PageHelper;
  7. import com.github.pagehelper.PageInfo;
  8. import com.infore.common.pinyin.PinyinUtils;
  9. import com.infore.common.util.ControllerUtil;
  10. import com.infore.model.ResponseDto;
  11. import com.infore.model.UserInfo;
  12. import com.infore.model.dto.UserInfoDto;
  13. import com.infore.service.UserInfoService;
  14. import gbap.log.Logger;
  15. import gbap.log.LoggerFactory;
  16. import io.swagger.annotations.Api;
  17. import io.swagger.annotations.ApiImplicitParam;
  18. import io.swagger.annotations.ApiImplicitParams;
  19. import io.swagger.annotations.ApiOperation;
  20. import java.util.List;
  21. import javax.annotation.Resource;
  22. import javax.ws.rs.core.MediaType;
  23. /**
    • 人员信息控制类
    • @author XiaChengwei
    • @date: 2017-07-14 16:45:29
    • */
    • @RestController
    • @RequestMapping(value = "/userInfo", produces = MediaType.APPLICATION_JSON)
    • @Api(value = "用户信息", description = "用户信息", produces = MediaType.APPLICATION_JSON)
    • public class UserInfoController {
    • private Logger logger = LoggerFactory.getLogger(getClass());
    • @Resource
    • UserInfoService service;
    • @ResponseBody
    • @RequestMapping(value = "/selectAllUsers", method = RequestMethod.GET)
    • @ApiOperation(value = "查询所有的人员信息并分页展示", notes = "查询所有的人员信息并分页展示")
    • @ApiImplicitParams({
    • @ApiImplicitParam(name = "page",value = "跳转到的页数", required = true, paramType = "query"),
    • @ApiImplicitParam(name = "size",value = "每页展示的记录数", required = true, paramType = "query")
    • })
    • public ResponseDto selectAllUsers(Integer page, Integer size) {
    • page = page == null || page <= 0 ? 1 : page;
    • size = size == null || size <= 5 ? 5 : size;
    • PageHelper.startPage(page, size);//PageHelper只对紧跟着的第一个SQL语句起作用
    • List<UserInfo> userInfoList = service.selectAllUsers();
    • PageInfo pageInfo = new PageInfo(userInfoList);
    • return ControllerUtil.returnDto(true, "成功", pageInfo);
    • }
    • @ResponseBody
    • @RequestMapping(value = "/selectContacts", method = RequestMethod.GET)
    • @ApiOperation(value = "查询通讯录人员信息", notes = "查询通讯录人员信息")
    • public ResponseDto selectContacts() {
    • List<UserInfo> list = service.selectContacts();
    • return ControllerUtil.returnDto(true, "成功", list);
    • }
    • @ResponseBody
    • @RequestMapping(value = "selectByUserNo", method = RequestMethod.GET)
    • @ApiOperation(value = "新增人员前先检测用户名是否可用", notes = "新增人员前先检测用户名是否可用")
    • @ApiImplicitParams({
    • @ApiImplicitParam(name = "user_no", value = "用户输入的用户名", required = true, paramType = "query")
    • })
    • public ResponseDto selectByUserNo(String user_no) {
    • UserInfo userInfo = service.selectByUserNo(user_no);
    • if(null == userInfo || "".equals(userInfo.getUserNo())) {
    • return ControllerUtil.returnDto(true, "此用户名可用", null);
    • }else {
    • return ControllerUtil.returnDto(false, "此用户名不可用", null);
    • }
    • }
    • @ResponseBody
    • @RequestMapping(value = "insertSelective", method = RequestMethod.POST)
    • @ApiOperation(value = "新增人员", notes = "新增人员")
    • public ResponseDto insertSelective(UserInfoDto userInfoDto) {
    • int count = 0;
    • PinyinUtils pinyin = new PinyinUtils();
    • try {
    • //新增人员之前先检查用户名是否可用
    • UserInfo userInfo = service.selectByUserNo(userInfoDto.getUserNo());
    • if(null != userInfo && !"".equals(userInfo.getUserNo())) {
    • return ControllerUtil.returnDto(false, "此用户名不可用", null);
    • }
    •      <span class="hljs-keyword">if</span>(<span class="hljs-keyword">null</span> != userInfoDto.getUserName() &amp;&amp; !<span class="hljs-string">""</span>.equals(userInfoDto.getUserName())) {
    •          <span class="hljs-comment">//获取姓名拼音并存在对象中</span>
    •          userInfoDto.setSpellName(pinyin.getPingYin(userInfoDto.getUserName()));
    •      }<span class="hljs-keyword">else</span> {
    •          <span class="hljs-keyword">return</span> ControllerUtil.returnDto(<span class="hljs-keyword">false</span>, <span class="hljs-string">"请输入姓名"</span>, count);
    •      }
    •      count = service.insertSelective(userInfoDto);
    •      <span class="hljs-keyword">if</span>(count &lt;= <span class="hljs-number">0</span>) {
    •          <span class="hljs-keyword">return</span> ControllerUtil.returnDto(<span class="hljs-keyword">false</span>, <span class="hljs-string">"失败"</span>, count);
    •      }<span class="hljs-keyword">else</span> {
    •          <span class="hljs-keyword">return</span> ControllerUtil.returnDto(<span class="hljs-keyword">true</span>, <span class="hljs-string">"成功"</span>, count);
    •      }
    •  } <span class="hljs-keyword">catch</span> (Exception e) {
    •      logger.error(<span class="hljs-string">"userInfo--insertSelective:系统异常"</span>);
    •      <span class="hljs-keyword">return</span> ControllerUtil.returnDto(<span class="hljs-keyword">false</span>, <span class="hljs-string">"系统异常"</span>, count);
    •  }
    • }

    • @ResponseBody

    • @RequestMapping(value = "updateByPrimaryKeySelective", method = RequestMethod.POST)

    • @ApiOperation(value = "根据id修改人员信息", notes = "根据id修改人员信息")

    • public ResponseDto updateByPrimaryKeySelective(UserInfoDto userInfoDto) {

    • int count = 0;

    • try {

    • count = service.updateByPrimaryKeySelective(userInfoDto);

    • if(count <= 0) {

    • return ControllerUtil.returnDto(false, "失败", count);

    • }else {

    • return ControllerUtil.returnDto(true, "成功", count);

    • }

    • } catch (Exception e) {

    • logger.error("userInfo--updateByPrimaryKeySelective:系统异常");

    • return ControllerUtil.returnDto(false, "系统异常", count);

    • }

    • }

    • @ResponseBody

    • @RequestMapping(value = "modifyPwdById", method = RequestMethod.GET)

    • @ApiOperation(value = "修改密码", notes = "修改密码")

    • @ApiImplicitParams({

    • @ApiImplicitParam(name = "id",value = "人员信息id", required = true, paramType = "query"),

    • @ApiImplicitParam(name = "security_code",value = "验证码", required = true, paramType = "query"),

    • @ApiImplicitParam(name = "password",value = "新密码", required = true, paramType = "query")

    • })

    • public ResponseDto updateByPrimaryKeySelective(Integer id, String security_code, String password) {

    • int count = 0;

    • try {

    • //先对验证码是否正确做验证(此处暂未处理)

    • UserInfoDto userInfoDto = new UserInfoDto();

    • userInfoDto.setId(id);

    • userInfoDto.setPassword(password);

    • count = service.modifyPwdById(userInfoDto);

    • if(count <= 0) {

    • return ControllerUtil.returnDto(false, "失败", count);

    • }else {

    • return ControllerUtil.returnDto(true, "成功", count);

    • }

    • } catch (Exception e) {

    • logger.error("userInfo--modifyPwdById:系统异常");

    • return ControllerUtil.returnDto(false, "系统异常", count);

    • }

    • }

    • @ResponseBody

    • @RequestMapping(value = "deleteByPrimaryKey", method = RequestMethod.GET)

    • @ApiOperation(value = "根据id删除人员信息", notes = "根据id删除人员信息")

    • @ApiImplicitParams({

    • @ApiImplicitParam(name = "id", value = "人员信息id", required = true, paramType = "query")

    • })

    • public ResponseDto deleteByPrimaryKey(Integer id) {

    • int count = 0;

    • try {

    • count = service.deleteByPrimaryKey(id);

    • if(count <= 0) {

    • return ControllerUtil.returnDto(false, "失败", count);

    • }else {

    • return ControllerUtil.returnDto(true, "成功", count);

    • }

    • } catch (Exception e) {

    • logger.error("userInfo--deleteByPrimaryKey:系统异常");

    • return ControllerUtil.returnDto(false, "系统异常", count);

    • }

    • }

    • @ResponseBody

    • @RequestMapping(value = "selectById", method = RequestMethod.GET)

    • @ApiOperation(value = "根据id查询人员的所有信息", notes = "根据id查询人员的所有信息")

    • @ApiImplicitParams({

    • @ApiImplicitParam(name = "id", value = "人员信息id", required = true, paramType = "query")

    • })

    • public ResponseDto selectById(Integer id) {

    • UserInfoDto dto = service.selectById(id);

    • return ControllerUtil.returnDto(true, "成功", dto);

    • }

    • }

五、访问

配置完成之后重启服务器,访问地址 http://localhost:8080/项目名/swagger-ui.html,如:

  1. http://localhost:8080/spring-mvc/swagger-ui.html

访问之后的效果图如下:


访问效果图

点击具体的接口展开详情,效果图如下:
















新增人员接口

/userInfo/selectById 接口中输入相关参数,点击Try it out 按钮查看接口的返回值,如下:

  1. {
  2. "success": true,
  3. "msg": "成功",
  4. "data": {
  5. "id": 1,
  6. "userNo": "admin",
  7. "userName": "管理员",
  8. "spellName": "guanliyuan",
  9. "password": "123",
  10. "userPhone": "18681558780",
  11. "userGender": 0,
  12. "createTime": "2017-06-27 01:56:28",
  13. "updateTime": "2017-07-26 15:56:05"
  14. }
  15. }

六、参考资料

源码地址

swagger2 与 springmvc 整合 生成接口文档

一步步完成Maven+SpringMVC+SpringFox+Swagger整合示例

Spring MVC中使用 Swagger2 构建Restful API

Spring MVC中使用Swagger生成API文档和完整项目示例

SwaggerUI用户手册

七、拓展延伸

RAP

  1. </div>
  2. </div>
posted @
2018-12-09 17:36 
学不死的程序员 
阅读(...) 
评论(...) 
编辑 
收藏

SpringMVC集成Swagger插件以及Swagger注解的简单使用的更多相关文章

  1. springmvc集成Ueditor插件实现图片上传2、

    一.下载Ueditor插件. 地址:http://ueditor.baidu.com/website/download.html 二.环境搭建. 具体可以参看http://fex.baidu.com/ ...

  2. spring-mvc集成 swagger

    问题1:spring-mvc集成 swagger, 配置好后界面 404, 原因: dispatcher-servlet.xml 文件中, 要在这上面 <!-- 启用spring mvc 注解 ...

  3. SpringMVC 中配置 Swagger 插件.

    一.简介 Swagger的目标是为REST API定义一个与语言无关的标准接口,允许用户发现和理解计算机服务的功能,而无需访问源代码.当通过Swagger正确定义时,用户可以用最少量的实现逻辑理解远程 ...

  4. NetCoreApi框架搭建(一、swagger插件使用)

    1.首先用vs2017创建新的项目 2.开始引入swagger插件 右击项目=>管理NuGet程序包=>搜索Swashbuckle.AspNetCore点击安装 3.打开Startup.c ...

  5. SpringMVC集成springfox-swagger2自动生成接口文档

    本节内容: 什么是Swaggger Springfox与Swagger的关系 SpringMVC集成springfox-swagger2 一.什么是Swaggger Swagger是一个流行的API开 ...

  6. MP实战系列(十)之SpringMVC集成SpringFox+Swagger2

    该示例基于之前的实战系列,如果公司框架是使用JDK7以上及其Spring+MyBatis+SpringMVC/Spring+MyBatis Plus+SpringMVC可直接参考该实例. 不过建议最好 ...

  7. 记录一次bug解决过程:eclipse集成lombok插件

    一 总结 eclipse集成插件lombok: 启动Spring Boot项目: sublime全局搜索关键字:ctrl + shift + F JDK8中的lambda表达式使用 二 BUG描述:集 ...

  8. SpringMVC 集成velocity

    前言 没有美工的时代自然少不了对应的模板视图开发,jsp时代我们用起来也很爽,物极必反,项目大了,数据模型复杂了jsp则无法胜任. 开发环境 idea2016.jdk1.8.tomcat8.0.35 ...

  9. eclipse集成testng插件

    一.TestNG简介 TestNG是一个开源自动化测试框架,它受到JUnit和NUnit的启发,而引入了许多新的创新功能,如依赖测试,分组概念,使测试更强大,更容易做到. 它旨在涵盖所有类别的测试:单 ...

随机推荐

  1. 【leetcode 简单】第十五题 加一

    给定一个非负整数组成的非空数组,在该数的基础上加一,返回一个新的数组. 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字. 你可以假设除了整数 0 之外,这个整数不会以零开头. 示例 1: ...

  2. Friends and Berries URAL - 2067 (计算三点共线和计算的时候的注意点)

    题目链接:https://cn.vjudge.net/problem/URAL-2067 具体思路:判断三点共线就可以了,只有一对点能满足,如果一对就没有那就没有满足的. 在计算的时候,要注意,如果是 ...

  3. 删除none的images

    脚本 #!/bin/bash docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop docker p ...

  4. 大图片上传(ImageIO,注意有的图片不能上传时因为他是tiff格式)

    一下是必要的: 1.enctype="multipart/form-data" 2. //不要使用myeclipse自动生成的get.set方法(struts2中的用法) publ ...

  5. Automation Testing - Best Practice(书写规范)

    Coding Standards Coding Standards are suggestions that will help us to write automation Scripts code ...

  6. 33 - 并发编程-线程同步-Event-lock

    目录 1 线程同步 1.1 Event 1.1.1 什么是Flag? 1.1.2 Event原理 1.1.3 吃包子 1.2 Lock 1.2.1 lock方法 1.2.2 计数器 1.2.3 非阻塞 ...

  7. 78.PL和PS通过BRAM交互共享数据

    本篇文章目的是使用Block Memory进行PS和PL的数据交互或者数据共享,通过zynq PS端的Master GP0端口向BRAM写数据,然后再通过PS端的Mater GP1把数据读出来,将结果 ...

  8. .NET 处理视频-MediaInfo 获取视频信息

    获取视频信息的组件很多,本节介绍的是:MediaFile. 第一步.添加 MediaInfoDotNet 在项目上右键,选择“管理 NuGet 程序包”,浏览以选中 MediaInfoDotNet,然 ...

  9. 2、gitlab 新建项目

    一.创建项目 1.访问gitlab并登录 http://git.xh.com/ 2.点击 Projects -> Starred projects 每个版本的gitlab不太一样但位置都差不多 ...

  10. “您查看的网页正在试图关闭窗口。是否关闭此窗口”的屏蔽方法(JavaScript)

    原文:http://www.cnblogs.com/tigerhuolh/archive/2011/04/14/2015634.html 用JS代码关闭窗口时会提示“您查看的网页正在试图关闭窗口.是否 ...