Swagger与SpringMVC项目整合

本文转自:http://blog.csdn.net/hayre/article/details/51027201

swagger 是一款提供在线文档测试,文档自动撰写的一款优秀的框架

首先,添加相关jar包

<!-- swagger框架 -->
<dependency>
	<groupId>com.mangofactory</groupId>
	<artifactId>swagger-springmvc</artifactId>
	<version>1.0.2</version>
</dependency>

<dependency>
	<groupId>org.codehaus.jackson</groupId>
	<artifactId>jackson-mapper-asl</artifactId>
	<version>1.9.13</version>
</dependency>
<dependency>
	<groupId>org.codehaus.jackson</groupId>
	<artifactId>jackson-core-asl</artifactId>
	<version>1.9.13</version>
</dependency>
然后编写swagger配置文件类(虽然swagger内置了一个springmvc标准配置文件,但是建议还是不要用)
/**
 * @author jiangjintai
 *
 */
@Configuration
@EnableWebMvc//如果没加这个会报错
@EnableSwagger//上面三个注释都是必要的,无添加便会出现莫名奇妙的错误
@ComponentScan(basePackages="myTeam.timeShop.controller")//添加这个注释,会自动扫描该类中的每一个方法自动生成api文档
public class MySwaggerConfig {

	  private SpringSwaggerConfig springSwaggerConfig;

	    /**
	     * Required to autowire SpringSwaggerConfig
	     */
	    @Autowired
	    public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig)
	    {
	        this.springSwaggerConfig = springSwaggerConfig;
	    }

	    /**
	     * Every SwaggerSpringMvcPlugin bean is picked up by the swagger-mvc
	     * framework - allowing for multiple swagger groups i.e. same code base
	     * multiple swagger resource listings.
	     */
	    @Bean
	    public SwaggerSpringMvcPlugin customImplementation()
	    {
	        return new SwaggerSpringMvcPlugin(this.springSwaggerConfig).apiInfo(apiInfo()).includePatterns(
	                ".*?");
	    }

	    private ApiInfo apiInfo()
	    {
	        ApiInfo apiInfo = new ApiInfo(
	                "时光商店", //应用名称
	                "内部人员开发文档",//文档名称
	                "本API为了解决安卓端与后台连接问题", //概述
	                "835379184@qq.com", //联系作者
	                "无许可证",//许可证明
	                "115.28.36.253:8080");//url地址
	        return apiInfo;
	    }
}
然后在springmvc的配置文件中加入类注入

<bean class="myTeam.timeShop.config.MySwaggerConfig" />  

这里要注意,记得设置springmvc的静态文件使用默认标记,防止有些js,css文件读取不到

<mvc:default-servlet-handler></mvc:default-servlet-handler>
然后到在GitHub上下载SwaggerUI项目,将dist下所有内容拷贝到本地项目webapp下面,结果目录如下图所示:

直接引用别人使用的网页,然后要修改一个数据加载地址,这里的index.html被我改成了index.jsp,用于域名的自动加载,修改index文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Swagger UI</title>
  <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" />
  <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" />
  <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
  <link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
  <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
  <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
  <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
  <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
  <script src='lib/handlebars-2.0.0.js' type='text/javascript'></script>
  <script src='lib/underscore-min.js' type='text/javascript'></script>
  <script src='lib/backbone-min.js' type='text/javascript'></script>
  <script src='swagger-ui.js' type='text/javascript'></script>
  <script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
  <script src='lib/jsoneditor.min.js' type='text/javascript'></script>
  <script src='lib/marked.js' type='text/javascript'></script>
  <script src='lib/swagger-oauth.js' type='text/javascript'></script>

  <!-- Some basic translations -->
  <!-- <script src='lang/translator.js' type='text/javascript'></script> -->
  <!-- <script src='lang/ru.js' type='text/javascript'></script> -->
  <!-- <script src='lang/en.js' type='text/javascript'></script> -->

  <script type="text/javascript">
    $(function () {
      var url = window.location.search.match(/url=([^&]+)/);
      if (url && url.length > 1) {
        url = decodeURIComponent(url[1]);
      } else {
        url = "${ctp}/timeShop/api-docs";<!--修改这个字段 -->
      }

      // Pre load translate...
      if(window.SwaggerTranslator) {
        window.SwaggerTranslator.translate();
      }
      window.swaggerUi = new SwaggerUi({
        url: url,
        dom_id: "swagger-ui-container",
        supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
        onComplete: function(swaggerApi, swaggerUi){
          if(typeof initOAuth == "function") {
            initOAuth({
              clientId: "your-client-id",
              clientSecret: "your-client-secret-if-required",
              realm: "your-realms",
              appName: "your-app-name", 
              scopeSeparator: ",",
              additionalQueryStringParams: {}
            });
          }

          if(window.SwaggerTranslator) {
            window.SwaggerTranslator.translate();
          }

          $('pre code').each(function(i, e) {
            hljs.highlightBlock(e)
          });

          addApiKeyAuthorization();
        },
        onFailure: function(data) {
          log("Unable to Load SwaggerUI");
        },
        docExpansion: "none",
        jsonEditor: false,
        apisSorter: "alpha",
        defaultModelRendering: 'schema',
        showRequestHeaders: false
      });

      function addApiKeyAuthorization(){
        var key = encodeURIComponent($('#input_apiKey')[0].value);
        if(key && key.trim() != "") {
            var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
            window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
            log("added key " + key);
        }
      }

      $('#input_apiKey').change(addApiKeyAuthorization);

      // if you have an apiKey you would like to pre-populate on the page for demonstration purposes...
      /*
        var apiKey = "myApiKeyXXXX123456789";
        $('#input_apiKey').val(apiKey);
      */

      window.swaggerUi.load();

      function log() {
        if ('console' in window) {
          console.log.apply(console, arguments);
        }
      }
  });
  </script>
</head>

<body class="swagger-section">
<c:set var="ctp" value="<%=request.getServletPath() %>"></c:set>
<div id='header'>
  <div class="swagger-ui-wrap">
    <a id="logo" href="http://swagger.io">swagger</a>
    <form id='api_selector'>
      <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
      <div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
      <div class='input'><a id="explore" href="#" data-sw-translate>Explore</a></div>
    </form>
  </div>
</div>

<div id="message-bar" class="swagger-ui-wrap" data-sw-translate> </div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>

补:

将index.html中的url改为本工程的url

if (url && url.length > 1) {
	url = decodeURIComponent(url[1]);
} else {
	//url = "http://petstore.swagger.io/v2/swagger.json";
        url = getWebRoot()+"api-docs"; // 设置自适应的url
}
// 获取服务host
function getWebRoot() {
  var url = window.location.href;
  url = url.replace(/#.*$/,"");
  return url;
}

OK,现在还不能生成文档,因为还没对控制器类添加相关注释,现在给出一个控制器类

/**
 * 
 */
package myTeam.timeShop.controller;

import myTeam.timeShop.bean.TbUser;
import myTeam.timeShop.service.CarouselService;
import myTeam.timeShop.service.SystemService;
import myTeam.timeShop.service.UserService;
import myTeam.timeShop.util.MyMapBuilder;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;

/**
 * @author jiangjintai
 *
 */
@RequestMapping("/client/commen")
@Controller
@Api(description="注册版块", value = "注册版块")//添加注释
public class RegisterController {
	@Autowired
	CarouselService carouselService;
	@Autowired
	UserService userService;
	@Autowired
	SystemService systemService;
	/**
 	 * 用户注册
 	 * jiangjintai
 	 * 2016年3月25日
 	 * @param userAccount
 	 * @param userPassword
 	 * @return
 	 */
 	@ResponseBody
 	@RequestMapping("/register")
	@ApiOperation(value = "用户注册",httpMethod="GET")//添加注释这里要把方法写上,string类型大写
 	public String register(                                                  //这里记得不能省略@RequestParam要写参数进去 不然无法进行在线测试
 			@ApiParam(value="用户账户",name="userAccount",required=true)@RequestParam("userAccount")String userAccount,//添加注释
 			@ApiParam(value="用户密码",name="userPassword",required=true)@RequestParam("userPassword")String userPassword){
 		if(userAccount.trim()==null||userPassword.trim()==null){
 			return JSON.toJSONString(new MyMapBuilder(0, "账户与密码不能为空").build());
 		}else{
 			if(userService.isExistByUserAccount(userAccount)){
 				return JSON.toJSONString(new MyMapBuilder(0, "对不起该账户已经存在").build());
 			}else{
 				
 				
 				userService.doSomeThingForUserRegister(userAccount,userPassword);
 				return JSON.toJSONString(new MyMapBuilder(1, "注册成功").build());
 			}
 		}
 	} 
}
这样就OK啦,访问你app里面index目录就可以查看到文档内容了下面附上相关的注释api

注释类型 Api

  • 必需元素概要

    所需元素  
    限定符和类型必需的元素和说明
    java.lang.Stringvalue
    api的短描述,将会显示在每个接口的缩略支干上面

注释类型 ApiParam


可选元素概要

可选元素  
限定符和类型可选元素和说明
java.lang.Stringaccess

java.lang.StringallowableValues
可运行的值类型
booleanallowMultiple
是否允许multiple类型
java.lang.StringdefaultValue
设置默认值
java.lang.Stringname
参数名,用于在线测试
booleanrequired
描述这个参数是否是必要的
java.lang.Stringvalue
对这个参数的描述

注释类型 ApiOperation

  • 必需元素概要

    所需元素  
    限定符和类型必需的元素和说明
    java.lang.Stringvalue
    对这个操作的描述(即对方法的描述)
  • 可选元素概要

    可选元素  
    限定符和类型可选元素和说明
    Authorization[]authorizations
    用户权限
    java.lang.Stringconsumes
    适合媒体类型
    java.lang.StringhttpMethod
    http方法如 GET, PUT, POST, DELETE, PATCH, OPTIONS(如果不设置改属性,每个接口将会被设置为任一方法都可使用)
    java.lang.Stringnickname
    这个接口的昵称
    java.lang.Stringnotes
    对这个方法的长描述(最好要添加这个方法)
    intposition

    java.lang.Stringproduces
    内容类型
    java.lang.Stringprotocols
    方法代理
    java.lang.Class<?>response
    返回vo类型
    java.lang.StringresponseContainer

    java.lang.Stringtags

详情请看:http://www.boyunjian.com/javadoc/org.apache.servicemix.bundles/org.apache.servicemix.bundles.swagger-annotations/1.3.2_1/_/com/wordnik/swagger/annotations/Api.html

详情请看:http://www.boyunjian.com/javadoc/org.apache.servicemix.bundles/org.apache.servicemix.bundles.swagger-annotations/1.3.2_1/_/com/wordnik/swagger/annotations/Api.html

至此你的接口api文档就搞定啦 部署上去咯