1. 程式人生 > >Springboot整合文件開發工具Swagger《SpringBoot學習七》

Springboot整合文件開發工具Swagger《SpringBoot學習七》

1. 為什麼要引用Swagger?

我們在之前的開發中大部分都是前後的分離,前端人員不知道要呼叫說明介面,但是後臺人員又不想寫介面文件,介面文件好麻煩,不知道有沒有同學寫過,特別麻煩,反正我不想寫,我在想如果有一個工具能在程式碼開發的時候就生成介面文件該多好,於是Swagger就解決了這個問題

2. 怎麼使用Swagger呢?

3. 引入maven依賴
<!--Swagger 是一個規範和完整的框架,
	用於生成、描述、呼叫和視覺化 RESTful 風格的 Web 服務-->
<!-- http://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.5.0</version>
</dependency>

<!-- http://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.5.0</version>
</dependency>

專案地址:https://github.com/HouChenggong/springboot_wagger

4. 配置通過SwaggerConfig
package com.pf.org.cms.configuration;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.async.DeferredResult;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import springfox.documentation.service.Contact;


@EnableSwagger2
@Configuration
public class SwaggerConfig {


    @Bean("使用者模組")
    public Docket userApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("使用者模組")
                .select()
                //下面的paths設定該模組攔截的路由
                .paths(PathSelectors.regex("/user.*"))
                .build()
                .apiInfo(userApiInfo());
    }


    @Bean("系統管理")
    public Docket xitongApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("系統管理")
                .select()
                //下面的paths設定該模組攔截的路由
                .paths(PathSelectors.regex("/system.*"))
                .build()
                .apiInfo(xitongApiInfo());
    }

    @Bean("全域性")
    //當然你要是不想一個一個的設定最簡單的是設定一個全域性模組,攔截所有的路由
    public Docket quanJuApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("全域性")
                //下面的paths設定該模組攔截的路由
                .pathMapping("/")
                .select()
                .build()
                .apiInfo(quanInfo());
    }

    private ApiInfo userApiInfo() {
//        apiInfo是介面文件的基本說明資訊,包括 標題 、描述、服務網址、聯絡人、版本等資訊;
//        主要使用者專案說明
//        這個是使用者管理模組的說明
        ApiInfo apiInfo = new ApiInfo(
                "本專案基於Swagger開發的API文件,使用者管理",//大標題
                "測試REST API,所有應用程式都可以通過JSON訪問Object模型資料",//小標題
                "1.0",//版本
                "NO terms of service",//服務條款
                new Contact("xiyou", "hiiumaa.club:8088", "
[email protected]
"),//作者 "專案github地址",//連結顯示文字 "https://github.com/HouChenggong/springboot_shiroMD5"//網站連結 ); return apiInfo; } private ApiInfo xitongApiInfo() { // apiInfo是介面文件的基本說明資訊,包括 標題 、描述、服務網址、聯絡人、版本等資訊; // 主要使用者專案說明 // 系統管理模組的說明 ApiInfo apiInfo = new ApiInfo( "本專案基於Swagger開發的API文件,系統管理",//大標題 "測試REST API,所有應用程式都可以通過JSON訪問Object模型資料",//小標題 "1.0",//版本 "NO terms of service",//服務條款 new Contact("xiyou", "hiiumaa.club:8088", "
[email protected]
"),//作者 "專案github地址",//連結顯示文字 "https://github.com/HouChenggong/springboot_shiroMD5"//網站連結 ); return apiInfo; } private ApiInfo quanInfo() { // apiInfo是介面文件的基本說明資訊,包括 標題 、描述、服務網址、聯絡人、版本等資訊; // 主要使用者專案說明 // 系統管理模組的說明 ApiInfo apiInfo = new ApiInfo( "本專案基於Swagger開發的API文件,全部專案",//大標題 "測試REST API,所有應用程式都可以通過JSON訪問Object模型資料",//小標題 "1.0",//版本 "NO terms of service",//服務條款 new Contact("xiyou", "hiiumaa.club:8088", "[email protected]"),//作者 "專案github地址",//連結顯示文字 "https://github.com/HouChenggong/springboot_shiroMD5"//網站連結 ); return apiInfo; } }
5. 解釋SwaggerConfig
  1. 每一個@Bean(“XXX”)都代表一個模組,因為開發的時候都是分模組開發的

  2. 同樣每個模組下面攔截的路由肯定不一樣,我們用 .paths(PathSelectors.regex("/system.*"))

    ​ 來設定本模組下面攔截的路由,同時指定info 每一個模組都可以有一個Info

  3. 當然如果你不想分模組開發,設定一個全域性路由攔截也是可以的,如上面的全域性路由攔截,但是不推薦

4. Controller配置

我們設定好了配置類,那我們的控制層該如何使用呢?

這裡我用一個controller來詳解

package com.pf.org.cms.hcg.system.controller;


        import com.pf.org.cms.configuration.RedisTest;
        import com.pf.org.cms.hcg.system.bean.PermissionDO;
        import com.pf.org.cms.hcg.system.bean.UserDO;
        import com.pf.org.cms.hcg.system.service.PermissionService;
        import com.pf.org.cms.hcg.system.service.UserNewService;
        import com.pf.org.cms.manage.RedisManager;
        import io.swagger.annotations.ApiOperation;
        import org.apache.shiro.SecurityUtils;
        import org.apache.shiro.authc.AuthenticationException;
        import org.apache.shiro.authc.IncorrectCredentialsException;
        import org.apache.shiro.authc.UsernamePasswordToken;

        import org.apache.shiro.subject.Subject;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.annotation.Value;
        import org.springframework.stereotype.Controller;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.bind.annotation.RequestParam;
        import org.springframework.web.bind.annotation.ResponseBody;

        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import javax.servlet.http.HttpSession;
        import java.io.PrintWriter;
        import java.io.UnsupportedEncodingException;
        import java.net.URLEncoder;
        import java.util.List;
        import java.util.Map;

/**
 * @author xiyou
 * @create 2017-11-21 17:08
 * @desc 系統管理控制層
 **/
@Controller
public class UserController {
    @Autowired
    UserNewService userNewService;

    @Autowired
    PermissionService permissionService;
    @Autowired
    RedisManager redisManager ;

    @Value("${spring.profiles.active}")
    private String profileActive;


    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @ApiOperation(value = "使用者登陸驗證" , notes = "swagger測試介面" )
    //使用者使用者名稱和密碼MD5加密後的驗證
    @RequestMapping(value = "/user/authenticate", method = RequestMethod.GET)
    @ResponseBody
    public String authenticate(@RequestParam("loginName") String loginName, @RequestParam("password") String password,
                               HttpServletRequest request, HttpSession session, HttpServletResponse response) {

        //把前端輸入的username和password封裝為token
        UsernamePasswordToken token = new UsernamePasswordToken(loginName, password);
        // 認證身份
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            session.setAttribute("user", subject.getPrincipal());
            log.info("登陸成功");
            return "success";
        } catch (Exception e) {
            log.info("登陸失敗");
            return "false";
        }


    }


    @ApiOperation(value = "Redis測試介面" , notes = "swagger測試介面" )
    @RequestMapping(value = "/demo", method = RequestMethod.GET)
    @ResponseBody
    public String testRedis(String key) {
        System.out.println("入參key為:"+key);
        String s = "查詢結果為:"+redisManager.getStr(key);
        return s;
    }


    @ApiOperation(value = "使用者使用者密碼許可權驗證的介面" , notes = "swagger測試介面" )
    @RequestMapping(value = "/system/authenticate",method = RequestMethod.POST)
    @ResponseBody
    public String testDemo(Map<String, Object> map) {
        System.out.println("入參key為:"+map.toString());
         UserDO demos = userNewService.getUserByLoginName("wanwan");
        map.put("data", demos);
        System.out.println(demos.toString());
        System.out.println(profileActive);
        log.debug("debug---log-------------" + demos.toString());
        log.info("info---log-------------" + demos.toString());
        log.warn("warn---log-------------" + demos.toString());
        log.error("error---log-------------" + demos.toString());
        return "success";
    }

}

5. controller配置說明
 @ApiOperation(value = "使用者登陸驗證" , notes = "swagger測試介面" )
    //使用者使用者名稱和密碼MD5加密後的驗證
    @RequestMapping(value = "/user/authenticate", method = RequestMethod.GET)
 @ApiOperation(value = "使用者使用者密碼許可權驗證的介面" , notes = "swagger測試介面" )
    @RequestMapping(value = "/system/authenticate",method = RequestMethod.POST)
  @ApiOperation(value = "Redis測試介面" , notes = "swagger測試介面" )
    @RequestMapping(value = "/demo", method = RequestMethod.GET)

這些是用來指定訪問的路由和路由資訊的說明的

同時method = RequestMethod.GET最好指定是POST還是get方法,為以後的RestFul開發做準備,同時這樣開發也比較規範

6. 生產環境配置

不知道有沒有同學注意到這個的,這個是application.yml指定生產環境的配置,其實在這裡面沒有說明用,我們只是用來複習一下之前的多環境開發的知識

  @Value("${spring.profiles.active}")
    private String profileActive;
7. 瀏覽器檢視

在瀏覽器中輸入http://localhost:8080/swagger-ui.html#/即可檢視預設生產的文件

類似於這樣,如果預設不寫是post還是get的話,他會生成所有的,看的時候就非常麻煩了,所有還是寫上

這時候我們就能看到我們設定的模組了,還有每一個模組的說明,當然每個模組只能看到自己的路由,同時還可以實現postman的功能,直接測試用例

注意一點:

shiro攔截,不能把swagger-ui.html#/這個攔截了,同時再貼下shiro的配置

 @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
    ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
    filterFactoryBean.setSecurityManager(securityManager);
    // 配置登入的url
    filterFactoryBean.setLoginUrl("/authenticate");
    //登入成功的url
    filterFactoryBean.setSuccessUrl("/home");
    // 配置未授權跳轉頁面
    filterFactoryBean.setUnauthorizedUrl("/errorPage/403");
    // 配置訪問許可權
    LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
    filterChainDefinitionMap.put("/css/**", "anon"); // 表示可以匿名訪問
    filterChainDefinitionMap.put("/fonts/**", "anon");
    filterChainDefinitionMap.put("/imgs/**", "anon");
    filterChainDefinitionMap.put("/js/**", "anon");
    filterChainDefinitionMap.put("/auth/**", "anon");
    filterChainDefinitionMap.put("/errorPage/**", "anon");
    filterChainDefinitionMap.put("/demo/**", "anon");
    filterChainDefinitionMap.put("/xitong/**", "anon");
    filterChainDefinitionMap.put("/user/**", "anon");
    filterChainDefinitionMap.put("/swagger-*/**", "anon");
    filterChainDefinitionMap.put("/swagger-ui.html/**", "anon");
    filterChainDefinitionMap.put("/webjars/**", "anon");
    filterChainDefinitionMap.put("/v2/**", "anon");

// 表示admin許可權才可以訪問
filterChainDefinitionMap.put("/admin/**", "roles[admin]");

// 表示需要認證才可以訪問
filterChainDefinitionMap.put("/*", "authc");
filterChainDefinitionMap.put("/**", "authc");
filterChainDefinitionMap.put("/*.*", "authc");
        filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return filterFactoryBean;
    }
專案地址:https://github.com/HouChenggong/springboot_wagger

傳送門