前言
swagger提供的接口文档相比传统的文档方式更加直观也更加高效,但是在网上找了很多关于Swagger与SpringMvc整合的资料,发现都比较繁琐,不是很满意,于是有了这篇博客,希望对大家有所帮助。
一、Swagger简介
Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。好了不多说了,直接讲解怎么集成restful文档。
本文主要讲解SpringMvc和swagger集成,关于SpringBoot和Swagger集成生成Restful api的教程可以参见我的另一篇博客:
二、项目结构
三、导入依赖
需要导入Swagger依赖包以及Spring和SpringMvc相关的依赖,这里使用的maven方式来管理依赖
Swagger依赖包括:
1、springfox-swagger2-2.5.0.jar
2、springfox-swagger-ui-2.5.0.jar
3、springfox-staticdocs-ui-2.5.0.jar
<?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>com.zjx</groupId>
<artifactId>swagger-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<spring.version>4.2.6.RELEASE</spring.version>
<servlet.version>3.1.0</servlet.version>
<swagger2.version>2.5.0</swagger2.version>
</properties>
<dependencies>
<!-- swagger开始 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-staticdocs</artifactId>
<version>${swagger2.version}</version>
</dependency>
<!-- swagger结束 -->
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!--web-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
四、自定义config
package com.zjx.swagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket userApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("用户")
.select()
.apis(RequestHandlerSelectors.basePackage("com.zjx.controller"))// 选择那些路径和api会生成document
.paths(PathSelectors.any()) // 对所有路径进行监控
.build()
.apiInfo(feedbackInfo());
}
private ApiInfo userInfo() {
ApiInfo apiInfo = new ApiInfo("用户相关接口",//大标题
"用户有关的接口,包括增加删除用户",//小标题
"0.1",//版本
"成都",
new Contact("zjx", "", ""),// 作者
"swagger url",//链接显示文字
""//网站链接
);
return apiInfo;
}
}
在实际开发中一般controller包里面根据不同的业务还要分为很多个包,那么每一个包都需要在config里面写一对上面的api和info,api方法必须要加@Bean注解,不然识别不了
五、自定义返回数据
1、Result.java 定义返回的数据
package com.zjx.constants;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
/**
* Created by zjx on 2017/6/29.
*
* @author zhaojiaxing
* @version V2.0
* Copyright (c)2016 tyj-版权所有
*/
@ApiModel
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
// 200成功
@ApiModelProperty(value = "错误码", name = "错误码")
private int code;
// 返回消息,成功为“success”,失败为具体失败信息
@ApiModelProperty(value = "错误码描述", name = "错误码描述")
private String desc;
// 返回数据
@ApiModelProperty(value = "数据对象", name = "数据对象")
private T data;
public Result() {
}
public Result(int code, String desc) {
this.code = code;
this.desc = desc;
}
public Result(int code, String desc, T data) {
this.code = code;
this.desc = desc;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "Result{" +
"code=" + code +
", desc='" + desc + '\'' +
", data=" + data +
'}';
}
}
2、Constants.java 状态码以及描述
package com.zjx.constants;
/**
* Created by zjx on 2017/6/29.
*
* @author zhaojiaxing
* @version V2.0
* Copyright (c)2016 tyj-版权所有
*/
public interface Constants {
////////////// 系统标识符 开始//////////////////
/**
* 错误 描述
*/
String MSG_ERROR = "error";
/**
* 成功 描述
*/
String MSG_SUCCESS = "OK";
////////////// 系统状态码 开始//////////////////
/**
* 请求失败
*/
int ERROR = 100;
/**
* 请求成功
*/
int SUCCESS = 200;
}
六、接口文档
package com.zjx.controller;
import com.zjx.constants.Constants;
import com.zjx.constants.Result;
import com.zjx.vo.UserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by zjx on 2017/6/29.
*
* @author zhaojiaxing
* @version V2.0
* Copyright (c)2016 tyj-版权所有
*/
@RestController
@RequestMapping("/user")
@Api(description = "用户相关接口文档")
public class SwaggerController {
@RequestMapping(value = "/add", method = RequestMethod.POST)
@ApiOperation(value = "添加用户", notes = "增加用户")
public Result<UserVo> add(@ApiParam(name = "token", value = "token",required = true) @RequestParam(name = "token", required = true) String token,
@ApiParam(name = "userName",value = "用户昵称",required = true)@RequestParam(name = "userName",required = true)String userName,
@ApiParam(name = "mobile",value = "手机",required = true)@RequestParam(name = "mobile",required = true)String mobile,
@ApiParam(required = true, name = "email", value = "邮箱") @RequestParam(name = "email", required = true) String email ) {
return new Result<UserVo>(Constants.SUCCESS,Constants.MSG_SUCCESS,new UserVo());
}
}
说明:
@Api(description = “用户相关接口文档”) 对该接口进行说明
@ApiParam 对参数进行解释
@ApiOperation 对方法进行解释
接口文档返回的实体bean(看自己项目需求,非必须)
package com.zjx.swagger.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* Created by zjx on 2017/6/29.
*
* @author zhaojiaxing
* @version V2.0
* Copyright (c)2016 tyj-版权所有
*/
@ApiModel(value = "用户信息")
public class UserVo {
@ApiModelProperty(value = "用户id", required = true) .
private long userId;
@ApiModelProperty(value = "昵称", required = true)
private long userName;
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public long getUserName() {
return userName;
}
public void setUserName(long userName) {
this.userName = userName;
}
}
说明:
@ApiModel(value = “用户信息”) 解释实体bean
@ApiModelProperty(value = “用户id”, required = true) 解释属性
七、配置文件
包括:
1、app-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="false">
<bean class="com.zjx.config.SwaggerConfig"/>
</beans>
2、app-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.zjx.swagger"/>
<mvc:default-servlet-handler/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".ftl"/>
</bean>
</beans>
3、app.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="app-beans.xml"/>
<import resource="app-mvc.xml"/>
</beans>
附:web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!--装入spring配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:app.xml</param-value>
</context-param>
<!-- 防止发生java.beans.Introspector内存泄露,应将它配置在ContextLoaderListener的前面 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!--<!– 以Listener方式启动spring –>-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--<!–编码过滤器–>-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--<!– 前端控制器的配置 –>-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
八、结束
以上配置完成后,通过tomcat启动该项目,至于怎么启动就不多说了,启动完成后在浏览器里面输入:
localhost:8000/swagger-ui.html 就可以打开Swagger文档了(这个根据自己项目的配置来定,我这里tomcat的端口设置的是8000,默认设置是8080,还有的在端口后面要跟项目名,这些都是自己定义的)。如下图:
点开swagger-controller就可以看到接口里面的方法了
点击Try it out 就可以试一下自己传的参数正确,以及返回值
ps: Swagger中的坑
一、返回的bean中如果有boolean类型,请注意,swagger识别的bean跟标准的javabean的规范是不一样的。
标准的javabean:
public boolean isDefault() {
return isDefault;
}
public void setDefault(boolean aDefault) {
isDefault = aDefault;
}
但是,对于swagger只能这样:
public boolean getIsDefault() {
return isDefault;
}
public void setIsDefault(boolean aDefault) {
isDefault = aDefault;
}
二、文件上传:
swagger并不支持(MultipartFile[] files)这种参数,如果是多个文件,只能写多个MultipartFile
最后附上github地址:> https://github.com/zhaojiaxing/Swagger-SpringMvc
欢迎大家下载使用,如果满意可以star一下
如果有问题,欢迎评论交流
也可以直接下载:> http://download.csdn.net/detail/zjx2016/9889131