Swagger+Spring mvc生成Restful接口文档

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。整体目标是使客户端和文件系统做为服务器以一样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,容许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。
这一次我将从零开始搭建一个工程来演示如何在Spring mvc中整合Swagger生成Restful接口文档。html

 

添加Maven依赖

<properties>
        <spring.version>4.1.7.RELEASE</spring.version>
        <version.jackson>2.4.4</version.jackson>
        <swagger.version>2.2.2</swagger.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>com.mangofactory</groupId>
            <artifactId>swagger-springmvc</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${version.jackson}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${version.jackson}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${version.jackson}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!--petstore是官方的一个demo,加入此依赖是为了稍后参考接口描述的编写-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-petstore</artifactId>
            <version>${swagger.version}</version>
        </dependency>

    </dependencies>

添加配置

添加一个ApplicationInitializer类,用于配置DispatchServlet启动:java

在工程中的resources文件夹下新建一个spring的文件夹,并新建一个dispatcher-servlet.xml的spring mvc配置文件,添加以下内容:web

添加一个SwaggerConfig类,用于配置Swagger接口的说明:spring

package com.bbd.liangdian.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * Created by Administrator on 2017/3/6.
 */
@EnableSwagger2
@Configuration
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.bbd.liangdian.apis"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("量点项目API文档")
                .version("1.0")
                .description("1:量点API,根据分组查找所须要的API.<br /> 2:注意请求的方法定义.")
                .build();
    }
}

新建一个GroupController,并编写测试方法:json

package yay.apidoc.controller;

    import io.swagger.annotations.*;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import yay.apidoc.model.UamGroup;

    import java.util.LinkedList;
    import java.util.List;

    /**
     * Created by yuananyun on 2015/11/23.
     */
    @Controller
    @RequestMapping(value = "/group", produces = {"application/json;charset=UTF-8"})
    @Api(value = "/group", description = "群组的相关操做")
    public class GroupController {
        @RequestMapping(value = "addGroup", method = RequestMethod.PUT)
        @ApiOperation(notes = "addGroup", httpMethod = "POST", value = "添加一个新的群组")
        @ApiResponses(value = {@ApiResponse(code = 405, message = "invalid input")})
        public UamGroup addGroup(@ApiParam(required = true, value = "group data") @RequestBody UamGroup group) {
            return group;
        }

        @RequestMapping(value = "getAccessibleGroups", method = RequestMethod.GET)
        @ApiOperation(notes = "getAccessibleGroups", httpMethod = "GET", value = "获取我能够访问的群组的列表")
        public List<UamGroup> getAccessibleGroups() {
            UamGroup group1 = new UamGroup();
            group1.setGroupId("1");
            group1.setName("testGroup1");

            UamGroup group2 = new UamGroup();
            group2.setGroupId("2");
            group2.setName("testGroup2");

            List<UamGroup> groupList = new LinkedList<UamGroup>();
            groupList.add(group1);
            groupList.add(group2);

            return groupList;
        }
    }

其中UamGroup的定义以下:api

package yay.apidoc.model;
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;

    /**
     * 群组
     */
    @ApiModel
    public class UamGroup {
        /**
         * 编号
         */
        @ApiModelProperty(value = "群组的Id", required = true)
        private String groupId;
        /**
         * 名称
         */
        @ApiModelProperty(value = "群组的名称", required = true)
        private String name;
        /**
         * 群组图标
         */
        @ApiModelProperty(value = "群组的头像", required = false)
        private String icon;

        public String getGroupId() {
            return groupId;
        }

        public void setGroupId(String groupId) {
            this.groupId = groupId;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getIcon() {
            return icon;
        }

        public void setIcon(String icon) {
            this.icon = icon;
        }
    }

配置web.xmltomcat

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <display-name>Archetype Created Web Application</display-name>

    <context-param>
        <!-- 配置 spring 容器启动的配置文件的路径 -->
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <context-param>
        <param-name>logbackConfigLocation</param-name>
        <param-value>classpath:logback.xml</param-value>
    </context-param>
    <listener>
        <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 配置编码过滤器 -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置tomcat启动时 启动SpringMVC -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
     <!-- 配置swagger-ui -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/swagger-ui.html</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <error-page>
        <error-code>404</error-code>
        <location>/index.html</location>
    </error-page>
</web-app>

好,如今咱们启动tomcat来看看效果: localhost:8080/swagger-ui.html服务器

解决中文乱码

能够看到,咱们写在方法上说明竟然成了乱码,为了解决这个问题,咱们新建一个转换类:mvc

package yay.apidoc.converter;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.databind.*;
    import org.springframework.http.HttpInputMessage;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

    import java.io.IOException;
    import java.text.SimpleDateFormat;

    /**
     * Created by yuananyun on 2015/11/23.
     */
    public class MappingJacksonHttpMessageConverterEx extends MappingJackson2HttpMessageConverter {
        private ObjectMapper objectMapper = new ObjectMapper();

        public MappingJacksonHttpMessageConverterEx() {
            super();
            DeserializationConfig deserializationConfig = objectMapper.getDeserializationConfig()
                    .without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            objectMapper.setConfig(deserializationConfig);
            // Configure serialization
            SerializationConfig serializationConfig = objectMapper.getSerializationConfig()
                    .without(SerializationFeature.FAIL_ON_EMPTY_BEANS);
            //serializationConfig.withDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            objectMapper.setConfig(serializationConfig);
            objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    //        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
            objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,true);

            setObjectMapper(objectMapper);
        }

        @Override
        protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage)
                throws IOException, HttpMessageNotReadableException {
            JavaType javaType = getJavaType(null, clazz);
            return this.objectMapper.readValue(inputMessage.getBody(), javaType);
        }
    }

而后修改dispatcher-servlet.xml中的mvc:annotation-driven配置节:app

<!-- Standard xml based mvc config-->
        <mvc:annotation-driven>
            <mvc:message-converters>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/html;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
                <bean class="yay.apidoc.converter.MappingJacksonHttpMessageConverterEx"/>
                <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
            </mvc:message-converters>
        </mvc:annotation-driven>

咱们再来看看效果: localhost:8080/swagger-ui.html

相关文章
相关标签/搜索