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", "neuq_hcg@163.com"),//作者
"项目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", "neuq_hcg@163.com"),//作者
"项目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", "neuq_hcg@163.com"),//作者
"项目github地址",//链接显示文字
"https://github.com/HouChenggong/springboot_shiroMD5"//网站链接
);
return apiInfo;
}
}
5. 解释SwaggerConfig
每一个@Bean(“XXX”)都代表一个模块,因为开发的时候都是分模块开发的
同样每个模块下面拦截的路由肯定不一样,我们用 .paths(PathSelectors.regex("/system.*"))
来设置本模块下面拦截的路由,同时指定info 每一个模块都可以有一个Info
当然如果你不想分模块开发,设置一个全局路由拦截也是可以的,如上面的全局路由拦截,但是不推荐
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