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
這裏寫圖片描述

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