1. 程式人生 > >Spring MVC中使用Swagger生成API文件和完整專案示例Demo,swagger

Spring MVC中使用Swagger生成API文件和完整專案示例Demo,swagger

轉載自:http://www.360doc.com/content/17/0914/17/16915_687184334.shtml 

 

實際專案中非常需要寫文件,提高Java服務端和Web前端以及移動端的對接效率。

  聽說Swagger這個工具,還不錯,就網上找了些資料,自己實踐了下。

 

一:Swagger介紹

Swagger是當前最好用的Restful API文件生成的開源專案,通過swagger-spring專案

實現了與SpingMVC框架的無縫整合功能,方便生成spring restful風格的介面文件,

同時swagger-ui還可以測試spring restful風格的介面功能。

 

官方網站為:http://swagger.io/

 

中文網站:http://www.sosoapi.com

 

 

二:Swagger與Spring MVC整合步驟

 

1.Maven關鍵配置

 

        

[html] view plain copy
  1. <dependency>  
  2.             <groupId>com.mangofactory</groupId>  
  3.             <artifactId>swagger-springmvc</artifactId>  
  4.             <version>1.0.2</version>  
  5.         </dependency>  
  6.   
  7.  <dependency>  
  8.         <groupId>org.springframework</groupId>  
  9.         <artifactId>spring-webmvc</artifactId>  
  10.         <version>4.1.6.RELEASE</version>  
  11.       </dependency>  
 

 

2. 外掛配置

   CustomJavaPluginConfig

 

3.複製swagger的相關js等靜態資源到webapp目錄。

   swagger-ui.js之類的。

   我copy過一次,但是有問題,最後從網上下載了一個專案,可以直接用的那種。

   然後自己再逐步改造。

 

4.啟動專案

   http://localhost:8080/

 

 

三、常見swagger註解一覽與使用

最常用的5個註解

@Api:修飾整個類,描述Controller的作用

@ApiOperation:描述一個類的一個方法,或者說一個介面

@ApiParam:單個引數描述

 

@ApiModel:用物件來接收引數

@ApiProperty:用物件接收引數時,描述物件的一個欄位

 

其它若干

 

@ApiResponse:HTTP響應其中1個描述

@ApiResponses:HTTP響應整體描述

 

 

 

@ApiClass

@ApiError

@ApiErrors

 

 

 

@ApiParamImplicit

@ApiParamsImplicit

 

四、關鍵程式碼和實際例子

    例子1:

   

[java] view plain copy
  1. @ApiOperation(value = "獲得使用者列表", notes = "列表資訊", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)  
  2.     @ResponseBody  
  3.     @RequestMapping(value = "list", method = RequestMethod.POST)  
  4.     public Result<User> list(  
  5.             @ApiParam(value = "分類ID", required = true) @RequestParam Long categoryId,  
  6.             @ApiParam(value = "token", required = true) @RequestParam String token) {  
  7.         Result<User> result = new Result<User>();  
  8.         User user = new User();  
  9.         result.setData(user);  
  10.         return result;  
  11.     }  
 

 

   @ApiParam(value = "token", required = true) @RequestParam String token

Web前端/移動端HTTP請求方式:直接把引數附帶到URL後面,或者用AJAX方法,表單提交。

 

  例子2:

[java] view plain copy
  1. @ApiOperation(value = "update使用者", notes = ")", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)  
  2.   @ResponseBody  
  3.   @RequestMapping(value = "update", method = RequestMethod.GET/*,produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE*/)  
  4.   public Result<String> update(User user) {  
  5.       String u = findUser(user);  
  6.       System.out.println(u);  
  7.       return null;  
  8.   }  
 

 

 當引數太多的時候,需要定義太多的引數,排版看起來很不舒服。

這個時候,可以使用物件來接收。

@ApiModel(value = "使用者物件",description="user2") 

public class User extends CommonParam{

 

}

Web前端/移動端HTTP請求方式:直接把引數附帶到URL後面,或者用AJAX方法,表單提交。

這裡面存在一個小問題,當後端用物件User來接收引數的時候,Swagger自帶的工具是這樣的:

 

這種形式,並不是表單提交,或者把引數附加到URL的後面。

我們只能手動構造URL,附帶引數去提交。

如果需要測試的話!

 

例子3:

[java] view plain copy
  1. public Result<String> add(@RequestBody User user) {  
  2.     String u = findUser(user);  
  3.     System.out.println(u);  
  4.     return null;  
  5. }  
 

 

Web前端/移動端HTTP請求方式:必須把引數,放到request請求的body中去。

後端不能直接用request.getParam("token")這種。

 

獲得request body中的資料,手動轉換成目標資料。

    String charReader(HttpServletRequest request) throws IOException {

 

        BufferedReader br = request.getReader();

 

        String str, wholeStr = "";

        while ((str = br.readLine()) != null) {

            wholeStr += str;

        }

        return wholeStr;

 

    }

 

個人推薦

1.引數不多的時候,用例子1,用@ApiParam註解生成文件。

  swagger視覺化介面,可以直接設定引數,傳送請求來測試

2.引數比較多的時候,用例子2,用物件來接收引數,在物件裡針對每個欄位,@ApiModelProperty註解生成文件。

   swagger視覺化介面,可以直接設定引數,但是無法接收到。

  因此,推薦使用其它HTTP請求或POST模擬工具,傳送請求,模擬測試。

 

不推薦例子3,不通用,侷限性比較大。

 

 

五、若干截圖

 

 

六、原始碼

[java] view plain copy
  1. package cn.fansunion.swagger.serverapi.controller;  
  2.   
  3. import org.springframework.http.MediaType;  
  4. import org.springframework.stereotype.Controller;  
  5. import org.springframework.web.bind.annotation.RequestBody;  
  6. import org.springframework.web.bind.annotation.RequestMapping;  
  7. import org.springframework.web.bind.annotation.RequestMethod;  
  8. import org.springframework.web.bind.annotation.RequestParam;  
  9. import org.springframework.web.bind.annotation.ResponseBody;  
  10.   
  11. import com.wordnik.swagger.annotations.Api;  
  12. import com.wordnik.swagger.annotations.ApiOperation;  
  13. import com.wordnik.swagger.annotations.ApiParam;  
  14.   
  15. /** 
  16.  * 小雷FansUnion-一個有創業和投資經驗的資深程式設計師-全球最大中文IT社群CSDN知名博主-排名第119 
  17.  * 部落格:http://blog.csdn.net/fansunion 
  18.  * 
  19.  */  
  20. @Api(value = "user", description = "使用者管理", produces = MediaType.APPLICATION_JSON_VALUE)  
  21. @Controller  
  22. @RequestMapping("user")  
  23. public class UserController {  
  24.   
  25.     // 列出某個類目的所有規格  
  26.     @ApiOperation(value = "獲得使用者列表", notes = "列表資訊", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)  
  27.     @ResponseBody  
  28.     @RequestMapping(value = "list", method = RequestMethod.POST)  
  29.     public Result<User> list(  
  30.             @ApiParam(value = "分類ID", required = true) @RequestParam Long categoryId,  
  31.             @ApiParam(value = "分類ID", required = true) @RequestParam Long categoryId2,  
  32.             @ApiParam(value = "token", required = true) @RequestParam String token) {  
  33.         Result<User> result = new Result<User>();  
  34.         User user = new User();  
  35.         result.setData(user);  
  36.         return result;  
  37.     }  
  38.   
  39.     @ApiOperation(value = "新增使用者", notes = "獲取商品資訊(用於資料同步)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)  
  40.     @ResponseBody  
  41.     @RequestMapping(value = "add", method = RequestMethod.POST)  
  42.     // @RequestBody只能有1個  
  43.     // 使用了@RequestBody,不能在攔截器中,獲得流中的資料,再json轉換,攔截器中,也不清楚資料的型別,無法轉換成java物件  
  44.     // 只能手動呼叫方法  
  45.     public Result<String> add(@RequestBody User user) {  
  46.         String u = findUser(user);  
  47.         System.out.println(u);  
  48.         return null;  
  49.     }  
  50.   
  51.     @ApiOperation(value = "update使用者", notes = "獲取商品資訊(用於資料同步)", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)  
  52.     @ResponseBody  
  53.     @RequestMapping(value = "update", method = RequestMethod.GET)  
  54.     public Result<String> update(User user) {  
  55.         String u = findUser(user);  
  56.         System.out.println(u);  
  57.         return null;  
  58.     }  
  59.   
  60.     private String findUser(User user) {  
  61.         String token = user.getToken();  
  62.         return token;  
  63.     }  
  64. }  


[java] view plain copy
  1. package cn.fansunion.swagger.serverapi.controller;  
  2.   
  3. import com.wordnik.swagger.annotations.ApiModel;  
  4. import com.wordnik.swagger.annotations.ApiModelProperty;  
  5.   
  6. /** 
  7.  * 小雷FansUnion-一個有創業和投資經驗的資深程式設計師-全球最大中文IT社群CSDN知名博主-排名第119 
  8.  * 部落格:http://blog.csdn.net/fansunion 
  9.  * 
  10.  */  
  11. @ApiModel(value = "使用者物件", description = "user2")  
  12. public class User extends CommonParam {  
  13.   
  14.     @ApiModelProperty(value = "商品資訊", required = true)  
  15.     private String name;  
  16.     @ApiModelProperty(value = "密碼", required = true)  
  17.     private String password;  
  18.   
  19.     @ApiModelProperty(value = "性別")  
  20.     private Integer sex;  
  21.     @ApiModelProperty(value = "密碼", required = true)  
  22.     private String token;  
  23.   
  24.     public String getToken() {  
  25.         return token;  
  26.     }  
  27.   
  28.     public void setToken(String token) {  
  29.         this.token = token;  
  30.     }  
  31.   
  32.     public String getName() {  
  33.         return name;  
  34.     }  
  35.   
  36.     public void setName(String name) {  
  37.         this.name = name;  
  38.     }  
  39.   
  40.     public String getPassword() {  
  41.         return password;  
  42.     }  
  43.   
  44.     public void setPassword(String password) {  
  45.         this.password = password;  
  46.     }  
  47.   
  48.     public Integer getSex() {  
  49.         return sex;  
  50.     }  
  51.   
  52.     public void setSex(Integer sex) {  
  53.         this.sex = sex;  
  54.     }  
  55.   
  56. }  

[java] view plain copy
  1. package cn.fansunion.swagger.serverapi.swagger;  
  2.   
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4. import org.springframework.context.annotation.Bean;  
  5. import org.springframework.context.annotation.Configuration;  
  6. import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;  
  7. import org.springframework.web.servlet.config.annotation.EnableWebMvc;  
  8. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;  
  9.   
  10. import com.mangofactory.swagger.configuration.SpringSwaggerConfig;  
  11. import com.mangofactory.swagger.models.dto.ApiInfo;  
  12. import com.mangofactory.swagger.paths.SwaggerPathProvider;  
  13. import com.mangofactory.swagger.plugin.EnableSwagger;  
  14. import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin;  
  15.   
  16. @Configuration  
  17. @EnableWebMvc  
  18. @EnableSwagger  
  19. public class CustomJavaPluginConfig extends WebMvcConfigurerAdapter {  
  20.   
  21.     private SpringSwaggerConfig springSwaggerConfig;  
  22.   
  23.     @Autowired  
  24.     public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {  
  25.         this.springSwaggerConfig = springSwaggerConfig;  
  26.     }  
  27.   
  28.     /** 
  29.      * 鏈式程式設計 來定製API樣式 後續會加上分組資訊 
  30.      *  
  31.      * @return 
  32.      */  
  33.     @Bean  
  34.     public SwaggerSpringMvcPlugin customImplementation() {  
  35.         return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)  
  36.                 .apiInfo(apiInfo()).includePatterns(".*")  
  37.                 .useDefaultResponseMessages(false)  
  38.             //  .pathProvider(new GtPaths())  
  39.                 .apiVersion("0.1").swaggerGroup("user");  
  40.   
  41.     }  
  42.   
  43.     private ApiInfo apiInfo() {  
  44.         ApiInfo apiInfo = new ApiInfo("小雷移動端API介面平臺",  
  45.                 "提供詳細的後臺所有Restful介面", "http://blog.csdn.net/FansUnion",  
  46.                 "[email protected]", "小雷部落格", "http://blog.csdn.net/FansUnion");  
  47.         return apiInfo;  
  48.     }  
  49.   
  50.     @Override  
  51.     public void configureDefaultServletHandling(  
  52.             DefaultServletHandlerConfigurer configurer) {  
  53.         configurer.enable();  
  54.     }  
  55.   
  56.     class GtPaths extends SwaggerPathProvider {  
  57.   
  58.         @Override  
  59.         protected String applicationPath() {  
  60.             return "/restapi";  
  61.         }  
  62.   
  63.         @Override  
  64.         protected String getDocumentationPath() {  
  65.             return "/restapi";  
  66.         }  
  67.     }  
  68.   
  69. }