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","[email protected]"),
                "", 
                "",
                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
这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章