欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring mvc - tutorial 2: spring + swagger

程序员文章站 2022-07-02 21:00:39
...

本文来玩玩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
spring mvc - tutorial 2: spring + 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
spring mvc - tutorial 2: spring + swagger