1. 程式人生 > >Swagger與SpringMVC專案整合

Swagger與SpringMVC專案整合

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為了解決安卓端與後臺連線問題", //概述
	                "
[email protected]
", //聯絡作者 "無許可證",//許可證明 "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>

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.String value
    api的短描述,將會顯示在每個介面的縮略支幹上面
  • 可選元素概要

    可選元素
    限定符和型別 可選元素和說明
    java.lang.String 適用於restful的路徑描述
    java.lang.String
    java.lang.String
    int 對資源列表的操作清晰請求
    java.lang.String
    java.lang.String

註釋型別 ApiParam


可選元素概要

可選元素
限定符和型別 可選元素和說明
java.lang.String
java.lang.String
boolean
java.lang.String
java.lang.String name 引數名,用於線上測試
boolean 描述這個引數是否是必要的
java.lang.String value 對這個引數的描述

註釋型別 ApiOperation

  • 必需元素概要

    所需元素
    限定符和型別 必需的元素和說明
    java.lang.String value 對這個操作的描述(即對方法的描述)
  • 可選元素概要

    可選元素
    限定符和型別 可選元素和說明
    java.lang.String
    java.lang.String http方法如 GET, PUT, POST, DELETE, PATCH, OPTIONS(如果不設定改屬性,每個介面將會被設定為任一方法都可使用)
    java.lang.String
    java.lang.String notes 對這個方法的長描述(最好要新增這個方法)
    java.lang.String
    java.lang.String
    java.lang.Class<?>
    java.lang.String tags
詳情請看: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文件就搞定啦 部署上去咯