Spring boot 初学

【原】swagger2markup+swagger2+sprin

2018-01-17  本文已影响1493人  曹赫洋

首先我们看一看效果图,高大上有木有啊有木有。

image.png
image.png
主要参考
https://leongfeng.github.io/2017/02/20/springboot-springfox-swagger2markup-spring-restdoc/
https://github.com/Swagger2Markup/spring-swagger2markup-demo
http://swagger2markup.github.io/swagger2markup/1.3.1/

这里笔者主要是参照官网的spring-swagger2markup-demo进行参考搭建的。

接下来我们来说一下是如何搞定的

1.在项目增加一个文件夹docs

直接从spring-swagger2markup-demo里把这个文件夹复制到自己的项目里就可以,复制的时候还有个manual_content1.adoc 和 manual_content2.adoc的文件,这个文件是接口文档的自定义说明部分,我用不到所以就删了,文件删除之后还要把index.adoc里对应的地方也删掉。


image.png

index.adoc 内容如下:

include::{generated}/overview.adoc[]
include::{generated}/paths.adoc[]
include::{generated}/security.adoc[]
include::{generated}/definitions.adoc[]

2.项目中添加maven依赖和插件

properties部分

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring.boot.version>1.5.8.RELEASE</spring.boot.version>
        
        <com.google.guava.version>19.0</com.google.guava.version>
        <springfox.version>2.5.0</springfox.version>
        <!--自定义的pagehelper版本  edit by sunxiaoyue-->
        <pagehelper.version>4.2.1</pagehelper.version>
        <javax.ws.rs-api.version>2.0</javax.ws.rs-api.version>
        <org.apache.poi.version>3.10-beta2</org.apache.poi.version>
        <jsch.version>0.1.46</jsch.version>
        <commons-lang3.verison>3.3.2</commons-lang3.verison>
        <commons-beanutils.version>1.8.3</commons-beanutils.version>
        <javax.mail.version>1.4.1</javax.mail.version>
        <swagger2markup.version>1.2.0</swagger2markup.version>
</properties>

dependency部分

<dependencies>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.5.6</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${com.google.guava.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-smile</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-afterburner</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${springfox.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springfox.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-bean-validators</artifactId>
            <version>${springfox.version}</version>
           
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-staticdocs</artifactId>
            <version>${springfox.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.restdocs</groupId>
            <artifactId>spring-restdocs-mockmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-jsonSchema</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.github.robwin</groupId>
            <artifactId>assertj-swagger</artifactId>
            <version>0.2.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.github.swagger2markup</groupId>
            <artifactId>swagger2markup-spring-restdocs-ext</artifactId>
            <version>${swagger2markup.version}</version>
            <scope>test</scope>
        </dependency>

        <!--使用log4j2 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
</dependencies>

maven plugin部分


    <build>
        <plugins>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!--docker 插件-->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.4.13</version>
                <configuration>
                    <forceTags>true</forceTags>
                    <!--<imageName>10.0.0.95:5000/${project.artifactId}:${project.version}</imageName>-->
                    <imageName>10.0.0.95:5000/JAVA_Account-Service:${project.version}</imageName>
                    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

            <!--Swagger2Markup相关插件 begin-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <systemPropertyVariables>
                        <io.springfox.staticdocs.outputDir>${swagger.output.dir}</io.springfox.staticdocs.outputDir>
                        <io.springfox.staticdocs.snippetsOutputDir>${swagger.snippetOutput.dir}</io.springfox.staticdocs.snippetsOutputDir>
                    </systemPropertyVariables>
                </configuration>
            </plugin>

            <!-- First, use the swagger2markup plugin to generate asciidoc -->
            <plugin>
                <groupId>io.github.swagger2markup</groupId>
                <artifactId>swagger2markup-maven-plugin</artifactId>
                <version>${swagger2markup.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>io.github.swagger2markup</groupId>
                        <artifactId>swagger2markup-import-files-ext</artifactId>
                        <version>${swagger2markup.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>io.github.swagger2markup</groupId>
                        <artifactId>swagger2markup-spring-restdocs-ext</artifactId>
                        <version>${swagger2markup.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <swaggerInput>${swagger.input}</swaggerInput>
                    <outputDir>${generated.asciidoc.directory}</outputDir>
                    <config>
                        <swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage>
                        <swagger2markup.pathsGroupedBy>TAGS</swagger2markup.pathsGroupedBy>

                        <swagger2markup.extensions.dynamicOverview.contentPath>${project.basedir}/src/docs/asciidoc/extensions/overview</swagger2markup.extensions.dynamicOverview.contentPath>
                        <swagger2markup.extensions.dynamicDefinitions.contentPath>${project.basedir}/src/docs/asciidoc/extensions/definitions</swagger2markup.extensions.dynamicDefinitions.contentPath>
                        <swagger2markup.extensions.dynamicPaths.contentPath>${project.basedir}/src/docs/asciidoc/extensions/paths</swagger2markup.extensions.dynamicPaths.contentPath>
                        <swagger2markup.extensions.dynamicSecurity.contentPath>${project.basedir}src/docs/asciidoc/extensions/security/</swagger2markup.extensions.dynamicSecurity.contentPath>

                        <swagger2markup.extensions.springRestDocs.snippetBaseUri>${swagger.snippetOutput.dir}</swagger2markup.extensions.springRestDocs.snippetBaseUri>
                        <swagger2markup.extensions.springRestDocs.defaultSnippets>true</swagger2markup.extensions.springRestDocs.defaultSnippets>
                    </config>
                </configuration>
                <executions>
                    <execution>
                        <phase>test</phase>
                        <goals>
                            <goal>convertSwagger2markup</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- Run the generated asciidoc through Asciidoctor to generate
                 other documentation types, such as PDFs or HTML5 -->
            <plugin>
                <groupId>org.asciidoctor</groupId>
                <artifactId>asciidoctor-maven-plugin</artifactId>
                <version>1.5.3</version>
                <!-- Include Asciidoctor PDF for pdf generation -->
                <dependencies>
                    <dependency>
                        <groupId>org.asciidoctor</groupId>
                        <artifactId>asciidoctorj-pdf</artifactId>
                        <version>1.5.0-alpha.10.1</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jruby</groupId>
                        <artifactId>jruby-complete</artifactId>
                        <version>1.7.21</version>
                    </dependency>
                </dependencies>
                <!-- Configure generic document generation settings -->
                <configuration>
                    <sourceDirectory>${asciidoctor.input.directory}</sourceDirectory>
                    <sourceDocumentName>index.adoc</sourceDocumentName>
                    <attributes>
                        <doctype>book</doctype>
                        <toc>left</toc>
                        <toclevels>3</toclevels>
                        <numbered></numbered>
                        <hardbreaks></hardbreaks>
                        <sectlinks></sectlinks>
                        <sectanchors></sectanchors>
                        <generated>${generated.asciidoc.directory}</generated>
                    </attributes>
                </configuration>
                <!-- Since each execution can only handle one backend, run
                     separate executions for each desired output type -->
                <executions>
                    <execution>
                        <id>output-html</id>
                        <phase>test</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>html5</backend>
                            <outputDirectory>${asciidoctor.html.output.directory}</outputDirectory>
                        </configuration>
                    </execution>

                    <execution>
                        <id>output-pdf</id>
                        <phase>test</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>pdf</backend>
                            <outputDirectory>${asciidoctor.pdf.output.directory}</outputDirectory>
                        </configuration>
                    </execution>

                </executions>
            </plugin>

            <!-- specify the main class for the manifest -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>io.github.robwin.swagger2markup.petstore.Application</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

            <!-- copy dependencies to the lib directory -->
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- copy the generated documents -->
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.7</version>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.outputDirectory}/static/docs</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>${asciidoctor.html.output.directory}</directory>
                                </resource>
                                <resource>
                                    <directory>${asciidoctor.pdf.output.directory}</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <!--Swagger2Markup相关插件 end-->
        </plugins>
    </build>

这里需要做如下几点说明

  1. log4j2的部分,官方的demo中使用的logback,但是我的项目里用的是log4j2,所以这里我有做处理,slf4j换成了log4j2,撰文时,官方的demo里用springfox.version是2.4.0,笔者全部升级为了2.5.0

3.swagger的使用部分

SwaggerConfig代码

package com.weds.account;

import com.google.common.base.Predicates;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import static springfox.documentation.builders.PathSelectors.ant;

import com.google.common.base.Predicates;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.Arrays;

import static java.util.Arrays.asList;
import static springfox.documentation.builders.PathSelectors.ant;

@EnableSwagger2
@Configuration
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfig {

    @Bean
    public Docket restApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.xx.account.web")).paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("账户微服务接口文档")
                .description("账户微服务接口文档")
                .contact(new Contact("XXX数据", "http://www.weds.com.cn", "caoheyang@weds.com.cn"))
                .license("Apache 2.0")
                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
                .version("1.0.0")
                .build();
    }
}

注意:如果你是参照官方文档添加的maven依赖,那这个SwaggerConfig 必须是在单元测试的包模块下,因为官方的依赖里springfox-bean-validators的scope是test,只有在test下才会被成功引入到SwaggerConfig 中。restApi部分采用的是basePackage方式,这样可以忽略比如actuator的rest接口也被拿来生成了接口文档。

3.REST接口以及实体类定义部分

package com.weds.account.web.inter;

import com.weds.framework.core.common.model.PagedResponse;

import com.weds.account.entity.req.*;
import com.weds.account.entity.resp.App_Account_Query_Resp;
import com.weds.framework.core.common.model.JsonResult;

import org.springframework.web.bind.annotation.*;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

/**
 * 应用账户相关的接口
 * Created by Caoheyang on 2018-01-06.
 */
@RestController
@RequestMapping(value = "/app/account", produces = {APPLICATION_JSON_VALUE})
public interface AppAccountInter {
    /**
     * 新增应用账户接口
     * Created by Caoheyang on 2018-01-06.
     *
     * @param req
     * @return
     */
    @PutMapping(path = "/add")
    public JsonResult add(@RequestBody App_Account_Add_Req req);

    /**
     * 修改应用账户信息接口
     * Created by Caoheyang on 2018-01-06.
     *
     * @param req
     * @return
     */
    @PostMapping(path = "/modify")
    public JsonResult modify(@RequestBody App_Account_Modify_Req req);

    /**
     * 修改应用账户密码接口
     * Created by Caoheyang on 2018-01-06.
     *
     * @param req
     * @return
     */
    @PostMapping(path = "/modify_pass")
    public JsonResult modifyPass(@RequestBody App_Account_Modify_Pass_Req req);

    /**
     * 删除应用账户接口
     * Created by Caoheyang on 2018-01-06.
     *
     * @param app_account 应用账户
     * @return
     */
    @DeleteMapping(path = "/delete/{app_account}")
    public JsonResult delete(@PathVariable("app_account") String app_account);

    /**
     * 查询某个应用账户接口
     * Created by Caoheyang on 2018-01-06.
     *
     * @return
     */
    @PostMapping(path = "/searchone")
    public JsonResult<App_Account_Query_Resp> searchOne();

    /**
     * 查询应用账户列表接口
     * Created by Caoheyang on 2018-01-06.
     *
     * @return
     */
    @PostMapping(path = "/search")
    public JsonResult<PagedResponse<App_Account_Query_Resp>> search();

    /**
     * 应用账户登陆接口
     * Created by Caoheyang on 2018-01-06.
     *
     * @param req
     * @return
     */
    @PostMapping(path = "/login")
    public JsonResult<App_Account_Query_Resp> login(@RequestBody App_Account_Login_Req req);
}

package com.weds.account.web;

import com.weds.account.entity.req.*;
import com.weds.account.entity.resp.App_Account_Query_Resp;
import com.weds.account.web.inter.AppAccountInter;
import com.weds.framework.core.common.model.JsonResult;
import com.weds.framework.core.common.model.PagedResponse;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;

/**
 * 应用账户相关服务的Controller Created by Caoheyang on 2018-01-06.
 */
@RestController
@Api(value = "应用账户管理", description = "应用账户相关的接口")
public class AppAccountController implements AppAccountInter {

    @ApiOperation(value = "新增应用账户接口", notes = "新增应用账户接口")
    @Override
    public JsonResult add(
            @ApiParam(value = "入参", required = true) @RequestBody App_Account_Add_Req req) {
        return null;
    }

    @ApiOperation(value = "修改应用账户信息接口", notes = "修改应用账户信息接口")
    @Override
    public JsonResult modify(
            @ApiParam(value = "入参", required = true) @RequestBody App_Account_Modify_Req req) {
        return null;
    }

    @ApiOperation(value = "修改应用账户密码接口", notes = "修改应用账户密码接口")
    @Override
    public JsonResult modifyPass(
            @ApiParam(value = "入参", required = true) @RequestBody App_Account_Modify_Pass_Req req) {
        return null;
    }

    @ApiOperation(value = "删除应用账户接口", notes = "删除应用账户接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "app_account", value = "应用账户", required = true, paramType = "path", dataType = "string")})
    @Override
    public JsonResult delete(@PathVariable("app_account") String app_account) {
        return null;
    }

    @ApiOperation(value = "查询某个应用账户接口", notes = "查询某个应用账户接口")
    @Override
    public  JsonResult<App_Account_Query_Resp>  searchOne() {
        return null;
    }

    @ApiOperation(value = "查询应用账户列表接口", notes = "查询应用账户列表接口")
    @Override
    public JsonResult<PagedResponse<App_Account_Query_Resp>>  search() {
        return null;
    }

    @ApiOperation(value = "应用账户登陆接口", notes = "应用账户登陆接口")
    @Override
    public  JsonResult<App_Account_Query_Resp>  login(
            @ApiParam(value = "入参", required = true) @RequestBody App_Account_Login_Req req) {
        return null;
    }
}
package com.weds.account.entity.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Map;

/**
 * 新增应用账户接口 入参
 * Created by Caoheyang on 2018-01-08.
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class App_Account_Add_Req implements Serializable{

    //应用账户,用一个应用下的应用账户具有唯一性
    @ApiModelProperty(required = true, dataType = "string", example = "admin",
            value = "应用账户,用一个应用下的应用账户具有唯一性")
    @Getter
    @Setter
    private String app_account;

    //应用账户标签,json格式,根据平台入驻时与账户微服务预定义的标签,由平台应用自行存储
    @ApiModelProperty(required = true, dataType = "string", example = "{\"class\":\"03\",\"type\":\"teacher\"}",
            value = "应用账户标签,json格式,根据平台入驻时与账户微服务预定义的标签,由平台应用自行存储")
    @Getter
    @Setter
    private Map<String, String> label;

    //应用账户密码 DES加密之后的密文
    @ApiModelProperty(required = true, dataType = "string", example = "FFWERWRFGP34DFWE",
            value = "应用账户密码,DES加密之后的密文")
    @Getter
    @Setter
    private String password;

    //角色编码,以”;角色码1;角色码2;”形式存储
    @ApiModelProperty(required = false, dataType = "string", example = ";0011;0032;",
            value = "角色编码,以”;角色码1;角色码2;”形式存储")
    @Getter
    @Setter
    private String role_nos;

    //添加人 默认值为system
    @ApiModelProperty(required = false, dataType = "string", example = "system",
            value = "添加人 默认值为system")
    @Getter
    @Setter
    private String inserted_by;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注1",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_1;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注2",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_2;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注3",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_3;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注4",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_4;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注5",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_5;
}

package com.weds.account.entity.resp;

import com.weds.account.entity.App_Account_Role;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;

import javax.management.relation.Role;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 查询某个应用账户接口 返回数据结构
 * Created by Caoheyang on 2018-01-09.
 */
public class App_Account_Query_Resp implements Serializable {
    //基础账户编号
    @ApiModelProperty(required = true, dataType = "int", example = "123",
            value = "基础账户编号")
    @Getter
    @Setter
    private int basic_acc_no;

    //应用账户
    @ApiModelProperty(required = true, dataType = "string", example = "admin",
            value = "应用账户")
    @Getter
    @Setter
    private String app_account;

    //身份证号码
    @ApiModelProperty(required = false, dataType = "string", example = "370685199010111215",
            value = "身份证号码")
    @Getter
    @Setter
    private String id_card;

    //真实姓名
    @ApiModelProperty(required = true, dataType = "string", example = "张三",
            value = "真实姓名")
    @Getter
    @Setter
    private String name;

    //性别 男 女
    @ApiModelProperty(required = true, dataType = "int", example = "男",
            value = "性别")
    @Getter
    @Setter
    private String sex;

    //手机号码1
    @ApiModelProperty(required = false, dataType = "string", example = "18888888888",
            value = "手机号码1")
    @Getter
    @Setter
    private String mobilephone;

    //手机号码2
    @ApiModelProperty(required = false, dataType = "string", example = "18888888888",
            value = "手机号码2")
    @Getter
    @Setter
    private String mobilephone2;

    //固话
    @ApiModelProperty(required = false, dataType = "string", example = "0535-80888888",
            value = "固话")
    @Getter
    @Setter
    private String telephone;

    //邮箱1
    @ApiModelProperty(required = false, dataType = "string", example = "weds@weds.com.cn",
            value = "邮箱1")
    @Getter
    @Setter
    private String email;

    //邮箱2
    @ApiModelProperty(required = false, dataType = "string", example = "weds1@weds.com.cn",
            value = "邮箱2")
    @Getter
    @Setter
    private String email2;

    //应用账户状态
    @ApiModelProperty(required = true, dataType = "int", example = "0",
            value = "应用账户状态")
    @Getter
    @Setter
    private int app_account_status;

    //标签  JSON数据体
    @ApiModelProperty(required = true, dataType = "string", example = "{\"class\":\"03\",\"type\":\"teacher\"}",
            value = "应用账户标签,json格式,根据平台入驻时与账户微服务预定义的标签,由平台应用自行存储")
    @Getter
    @Setter
    private Map<String, String> label;

    //角色,信息 JONS 数组
    @ApiModelProperty(required = true, dataType = "string", example = "admin",
            value = "角色数组")
    @Getter
    @Setter
    private List<App_Account_Role> role_nos;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注1",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_1;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注2",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_2;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注3",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_3;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注4",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_4;

    //备用标注,应用自定义存储,自行解析
    @ApiModelProperty(required = false, dataType = "string", example = "备注5",
            value = "备用标注,应用自定义存储,自行解析")
    @Getter
    @Setter
    private String column_5;
}

注意:
1.我这里用了lombok所以没有get,set方法,只有 @Getter和@Setter注解
2.在与swagger2markup的集成中发现,必须用@ApiParam注解,而且实体上不可以加ApiModel否则swagger2markup部分的生成会失败,无法映射接口的入参和返回值部分。
3.在swagger2中response部分不需要写,关于泛型部分也会自己直接映射的。

  1. @ApiImplicitParam在 @RequestBody联合使用的过程中,在swaggerui下没问题,但是在swagger2markup下是有问题的,无法生成swagger2markup文档,需要注意!

4.使用swagger2markup生成文档

1.需要新建一个Swagger2MarkupTest类,代码如下

package com.weds.account;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;

import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@AutoConfigureRestDocs(outputDir = "build/asciidoc/snippets")
@SpringBootTest(classes = {AccountServiceApplication.class, SwaggerConfig.class})
@AutoConfigureMockMvc
public class Swagger2MarkupTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void createSpringfoxSwaggerJson() throws Exception {
        //String designFirstSwaggerLocation = Swagger2MarkupTest.class.getResource("/swagger.yaml").getPath();

        String outputDir = System.getProperty("io.springfox.staticdocs.outputDir");
        MvcResult mvcResult = this.mockMvc.perform(get("/v2/api-docs")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andReturn();

        MockHttpServletResponse response = mvcResult.getResponse();
        String swaggerJson = response.getContentAsString();
        Files.createDirectories(Paths.get(outputDir));
        try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputDir, "swagger.json"), StandardCharsets.UTF_8)){
            writer.write(swaggerJson);
        }
    }
}

2.执行maven 的clean命令 然后执行test命令

image.png
插件会自动生成接口文件到target下,文件是adoc格式的。
由于插件会提现把接口文档生成为adoc文件,放到target下,所以对项目的实际运行速度毫无影响。
这时如果执行spring boot的run 命令,请求http://localhost:1234/docs/index.html发现是500的错误,但是如果把执行maven的package命令,然后在执行spring boot的run 命令或者 java -jar 项目.jar 把项目跑起来,然后在访问 http://localhost:1234/docs/index.html 就ok了,并且 http://localhost:1234/swagger-ui.html 也是ok的。

github开源代码:https://github.com/caoheyang/swagger2markupdemo
oschina开源代码:https://gitee.com/caoheyang/swagger2markupdemo
请注意代码中还有很多的依赖是自己封装的,请参照博客查找swagger2markup部分即可。

上一篇下一篇

猜你喜欢

热点阅读