spring mvc - tutorial 2: spring + swagger
本文来玩玩swagger,依然使用spring。那么如何把swagger用到spring里面去呢?网上看了一下,发现是通过springfox suite + swagger ui实现的。
简单总结一下相关知识(OAS规范 => Swagger framework => Swagger tools => springfox swagger):
- OpenAPI规范(以前称为Swagger Specification)是用于描述RESTful API的定义格式。
该规范创建了一个RESTful接口,通过有效地映射与其关联的所有资源和操作,轻松开发和使用API。
参见:https://swagger.io/specification/ - Swagger是全球最大的OAS(OpenAPI)规范的[API开发者工具]框架。
Swagger框架由一组用于设计,构建和记录RESTful API的核心工具支持。
参见:https://swagger.io/tools/
核心工具包括:
Swagger Core:Java-related libraries for creating, consuming, and working with Swagger definitions
Swagger Codegen:A code generation framework for building Client SDKs, servers, and documentation from Swagger Definitions
Swagger UI:An HTML5 based UI for exploring and interacting with a Swagger defined API
Swagger Editor:Browser based editor for authoring Swagger definitions using YAML
其它工具还包括:
Swagger JS:Javascript library for connecting to Swagger-defined APIs from browser and node.js applications
Swagger Node:Design-driven server implementation for node.js
Swagger Parser:Standalone library for parsing Swagger definitions from Java
Validator-Badge:Standalone web service which validates swagger definitions dynamically
参见:https://github.com/swagger-api/swagger.io/blob/wordpress//tools/index.md
简单说一下springfox:
- springfox套件是用于spring项目自动生成机器和人类可读的JSON API。
- springfox工作原理是在运行时检查程序,根据spring配置,类结构,编译时java注解来推断API语义。
- springfox的目标之一就是扩展对其它针对JSON API规范和文档标准的支持,比如swagger。
参见:http://springfox.github.io/springfox/
下面就按官方文档,写个程序试试。
1. Spring mvc + springfox swagger1
https://github.com/springfox/springfox/blob/v1.0.2/README.md
一看文档,发现又有这种版本问题,是让人很不爽的体验。。。
这个有些老了,就不去折腾了。
2. Spring mvc + springfox swagger2
https://github.com/springfox/springfox/blob/master/docs/transitioning-to-v2.md
2.1 新建一个简单的spring mvc restful web app
POM文件中添加依赖:包括spring + springfox + swagger
<?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>
。。。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.0.5.RELEASE</spring.version>
<jackson.version>2.9.5</jackson.version>
<springfox.version>2.8.0</springfox.version>
<swagger.version>1.5.19</swagger.version>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</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>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</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-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-core</artifactId>
<version>${swagger.version}</version>
</dependency>
</dependencies>
。。。
</project>
2.2 添加spring配置文件
src/main/resouces/spring.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Spring bean配置 -->
<context:component-scan base-package="example.model" />
</beans>
src/main/resouces/spring-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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!-- 使用注解驱动Spring MVC -->
<mvc:annotation-driven/>
<!-- swagger配置开始 -->
<!-- Serve static content-->
<mvc:default-servlet-handler/>
<bean class="example.config.MySwaggerConfig"/>
<!-- Direct static mappings, 把swagger-ui的dist目录下的东西放到src/main/webapp/WEB-INF/swagger -->
<mvc:resources mapping="/swagger/**" location="/WEB-INF/swagger/"/>
<!-- 如果把swagger-ui的dist目录下的东西直接放到src/main/webapp目录下,则使用下面这个配置-->
<!--<mvc:resources mapping="*.html" location="/"/>-->
<!-- swagger配置结束 -->
<!-- 定义扫描的包,用以加载对应的控制器和其它一些组件 -->
<context:component-scan base-package="example.controller"/>
</beans>
2.3 配置web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 配置Spring IoC配置文件的路径,其默认值为/WEB-INF/applicationContext.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!-- 配置ContextLoaderListener用以初始化Spring IoC -->
<!-- ContextLoaderListener实现了ServletContextListener接口;
ServletContextListener的作用是可以在整个Web工程前后加入自定义代码,
也可以在Web关闭时完成Spring IoC容器资源的释放 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置DispatcherServlet -->
<!-- 配置了servlet-name为dispatcher,默认需要一个/WEB-INF/dispatcher-servlet.xml的文件与之对应 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 在服务器启动时就初始化 -->
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Servlet拦截配置 -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.4 下载swagger-ui并把dist放到项目中
本例使用swagger-ui Ver.2.2.10:
https://github.com/swagger-api/swagger-ui/tree/v2.2.10
下载之后,dist目录下的所有文件放入目录:src/main/webapp/WEB-INF/swagger
其中的index.html里面有默认的url,可以修改成我们自己的地址http://localhost:8080/v2/swagger.json,不改也没有关系。
<script type="text/javascript">
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = "http://petstore.swagger.io/v2/swagger.json";
}
2.5 添加swagger configuration
MySwaggerConfig.java
各配置项的含义见springfox的说明文档
package example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
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.swagger.web.*;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
@Configuration
@EnableWebMvc
@EnableSwagger2
public class MySwaggerConfig {
@Bean
public Docket getApiInfo() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("restful api")
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.apiInfo(outApiInfo());
}
private ApiInfo outApiInfo() {
return new ApiInfo(
"this is title",
"this is description",
"1.0.0",
"http://www.example.com",
new Contact("your name","website","aaa@qq.com"),
"",
"",
new ArrayList()
);
}
@Bean
public UiConfiguration getUiConfig() {
return UiConfigurationBuilder.builder()
.deepLinking(true)
.displayOperationId(false)
.defaultModelsExpandDepth(1)
.defaultModelExpandDepth(1)
.defaultModelRendering(ModelRendering.of("schema")) //ModelRendering.EXAMPLE
.displayRequestDuration(false)
.docExpansion(DocExpansion.NONE)
.filter(false)
.maxDisplayedTags(null)
.operationsSorter(OperationsSorter.ALPHA)
.showExtensions(false)
.tagsSorter(TagsSorter.ALPHA)
//.supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS)
.validatorUrl(null)
.build();
}
}
2.6 加controller/model实现简单接口,并添加swagger注解
MyController.java
package example.controller;
import example.model.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/test")
@Api(tags = {"示例API"}, description = "MyController")
public class MyController {
/**
* 接收一个字符串,返回一个字符串
* @param name
* @return
*/
@ResponseBody
@RequestMapping(value="getuser")
@ApiOperation(httpMethod = "GET", value = "输入name", notes = "输入name,返回一串字符")
public String getUser1(@ApiParam(required = true, value="name") @RequestParam(value = "name") String name){
return "you passed a string: " + name;
}
/**
* 输入json,经过springmvc数据绑定直接映射成了java对象
* @param user
* @return json,java对象会自动转换成json字符串
*/
@ResponseBody
@RequestMapping(value="postuser", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
@ApiOperation(httpMethod = "POST", value = "输入user", notes = "接收user,返回user")
public User getUser2(@RequestBody User user){
return user;
}
}
user.java
package example.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel
public class User {
@ApiModelProperty(position = 1, value = "用户ID", example = "100", notes = "用户ID")
private int id;
@ApiModelProperty(position = 2, value = "姓名", example = "张三疯", notes = "用户姓名")
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.7 执行结果
运行之后,浏览器中输入:http://localhost:8080/swagger-ui.html
推荐阅读
-
你知道@RequestMapping的name属性有什么用吗?【享学Spring MVC】
-
Spring Boot 2.X整合Spring-cache(让你的网站速度飞起来)
-
关于Spring MVC在Controller层中注入request的坑详解
-
在Spring Boot中使用swagger-bootstrap-ui的方法
-
干货分享:ASP.NET CORE(C#)与Spring Boot MVC(JAVA)异曲同工的编程方式总结
-
Spring Boot 2 - 初识与新工程的创建
-
基于Maven 的 Spring MVC
-
Spring+Struts2整合
-
struts2、hibernate、spring的工作原理[简明易懂]
-
Spring源码剖析2:Spring IOC容器的加载过程