- 一、项目构建
- 1.1 构建父项目 pom
- 1.2 构建server项目结构
- 1. 创建配置文件 application.yml
- 2. 启动类 YebApplication
- 3. 常用jar配置
- 1.3 逆向工程——代码生成器(AutoGenerator)
- 1. 添加pom依赖
- 2. 构建代码生成器类
- 二、JWT 工具类的编写
- 2.1 配置pom与配置文件
- 1. pom准备
- 2. application.yml配置
- 2.2 工具类的编写
- 1. JWT工具类编写(JwtTokenUtil)
- 2. 公共返回对象的封装
- 三、正式开发
- 3.1 登录开发(通过security实现安全框架)
- 1. 创建登录实体类 AdminLoginParam
- 2. 登录的Controller层
- 3. 登录的业务层Service
- 3.2获取用户的信息开发
- 1.获取用户信息的Controller层(和登录在同一个Controller)
- 2. 获取用户信息的Service
- 3.3 Security的配置类
- 1. SecurityConfig配置
- 2. Jwt登录授权过滤器实现
- 3. 未授权结果返回
- 4. 未登录或登录失效返回
- 四、Swagger2配置
- 4.1 pom
- 4.2 swagger配置类
1.2 构建server项目结构 1. 创建配置文件 application.yml4.0.0 yeb_server yeb_generator org.springframework.boot spring-boot-starter-parent 2.6.2 com.jzq yeb 0.0.1-SNAPSHOT yeb Demo project for Spring Boot 11 pom
server:
# 端口
port: 7777
spring:
# 数据源配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/yeb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: Seven597
hikari:
# 连接池名
pool-name: DateHikariCP
# 最小空闲连接数
minimum-idle: 5
# 空闲连接存活最大时间,默认600000(10分钟)
idle-timeout: 180000
# 最大连接数 (10)
maximum-pool-size: 10
# 从连接池返回的连接自动提交
auto-commit: true
# 连接最大存活时间,0表示永久,默认为1800000(30分钟)
max-lifetime: 1800000
# 连接超时时间, 默认30000 (30秒)
connection-timeout: 30000
# 测试连接是否可用的查询语句
connection-test-query: 1
# Mybatis-plus配置
mybatis-plus:
# 配置Mapper映射文件
mapper-locations: classpath*:/mapper
@SpringBootApplication
@MapperScan("com.jzq.server.mapper")
public class YebApplication {
public static void main(String[] args) {
SpringApplication.run(YebApplication.class, args);
}
}
3. 常用jar配置
1.3 逆向工程——代码生成器(AutoGenerator)4.0.0 yeb com.jzq 0.0.1-SNAPSHOT yeb_server yeb_server http://www.example.com UTF-8 1.8 1.8 junit junit 4.11 test org.springframework.boot spring-boot-starter-web org.projectlombok lombok true mysql mysql-connector-java runtime com.baomidou mybatis-plus-boot-starter 3.3.1.tmp io.springfox springfox-swagger2 2.7.0 com.github.xiaoymin swagger-bootstrap-ui 1.9.6 maven-clean-plugin 3.1.0 maven-resources-plugin 3.0.2 maven-compiler-plugin 3.8.0 maven-surefire-plugin 2.22.1 maven-jar-plugin 3.0.2 maven-install-plugin 2.5.2 maven-deploy-plugin 2.8.2 maven-site-plugin 3.7.1 maven-project-info-reports-plugin 3.0.0
Mybatis-plus地址
1. 添加pom依赖2. 构建代码生成器类org.springframework.boot spring-boot-starter-web com.baomidou mybatis-plus-boot-starter 3.3.1.tmp com.baomidou mybatis-plus-generator 3.3.1.tmp org.freemarker freemarker mysql mysql-connector-java runtime
package com.jzq.generator;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CodeGenerator {
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/yeb-generator/src/main/java");
//作者
gc.setAuthor("seven");
//打开输出目录
gc.setOpen(false);
//xml开启 baseResultMap
gc.setbaseResultMap(true);
//xml 开启baseColumnList
gc.setbaseColumnList(true);
// 实体属性 Swagger2 注解
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/yeb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia" +
"/Shanghai");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("Seven597");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.jzq.server")
.setEntity("pojo")
.setMapper("mapper")
.setService("service")
.setServiceImpl("service.impl")
.setController("controller");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
// String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/yeb-generator/src/main/resources/mapper/"
+ tableInfo.getEntityName() + "Mapper"
+ StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
//数据库表映射到实体的命名策略
strategy.setNaming(NamingStrategy.underline_to_camel);
//数据库表字段映射到实体的命名策略
strategy.setColumnNaming(NamingStrategy.no_change);
//lombok模型
strategy.setEntityLombokModel(true);
//生成 @RestController 控制器
strategy.setRestControllerStyle(true);
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
//表前缀
strategy.setTablePrefix("t_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
二、JWT 工具类的编写
2.1 配置pom与配置文件
1. pom准备
org.springframework.boot
spring-boot-starter-security
2.5.5
io.jsonwebtoken
jjwt
0.9.1
2. application.yml配置
# JWT jwt: # JWT存储的请求头 tokenHeader: Authorization # JWT 解密加密使用的密钥 secret: yeb-secret # JWT的超期限时间(30*60*24) expiration: 604800 # JWT 负载中拿到开头 tokenHead: Bearer2.2 工具类的编写 1. JWT工具类编写(JwtTokenUtil)
package com.jzq.server.config.security;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtTokenUtil {
private static final String CLAIM_KEY_USERNAME = "sub";
private static final String CLAIM_KEY_CREATED = "created";
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
public String generateToken(UserDetails userDetails) {
Map claims = new HashMap<>();
claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
claims.put(CLAIM_KEY_CREATED, new Date());
return generateToken(claims);
}
public String generateToken(Map claims) {
System.out.println("secret:"+secret);
return Jwts.builder()
.setClaims(claims) // 设置载荷
.setExpiration(generateExpirationDate()) // 设置失效时间
.signWith(SignatureAlgorithm.HS512, secret) // 设置签名
.compact();
}
public Date generateExpirationDate() {
// 失效时间是就当前系统时间加 有效时间
return new Date(System.currentTimeMillis() + expiration*1000);
}
public String getUserNameFromToken(String token) {
String username;
try {
Claims claims = getUserClaimFromToken(token);
username = claims.getSubject();
}catch (Exception e) {
e.printStackTrace();
username = null;
}
return username;
}
public Claims getUserClaimFromToken(String token) {
Claims claims = null;
try {
claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
e.printStackTrace();
}
return claims;
}
public Boolean validateToken(String token, UserDetails userDetails) {
String username = getUserNameFromToken(token); // 终归是来源于token的
// 然后在token有效的前提下对比用户名是否一致
return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
}
public boolean isTokenExpired(String token) {
Date expireDate = getExpiredDateFromToken(token); // 拿到载荷里设置的有效时间
return expireDate.before(new Date()); // 验证载荷里的时间是否以及失效(失效返回true)
}
public Date getExpiredDateFromToken(String token) {
Claims claims = getUserClaimFromToken(token);
return claims.getExpiration();
}
public boolean canRefresh(String token) {
return !isTokenExpired(token);
}
public String refreshToken(String token) {
Claims claims = getUserClaimFromToken(token);
claims.put(CLAIM_KEY_CREATED, new Date());
return generateToken(claims);
}
}
2. 公共返回对象的封装
package com.jzq.server.config.result;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RespBean {
private long code;
private String message;
private Object result;
public static RespBean success(String message) {
return new RespBean(200, message, null);
}
public static RespBean success(String message, Object result) {
return new RespBean(200, message, result);
}
public static RespBean error(String message) {
return new RespBean(500, message, null);
}
}
三、正式开发
3.1 登录开发(通过security实现安全框架)
1. 创建登录实体类 AdminLoginParam
swagger文档注解:
@ApiModel : 注释在类上,用于描述
@ApiModelProperty: 注释在属性上, 用于描述和控制权限(是否必填)
package com.jzq.server.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "AdminLogin对象", description = "") // swagger文档注解
public class AdminLoginParam {
@ApiModelProperty(value = "用户名", required = true)
private String username;
@ApiModelProperty(value = "密码", required = true)
private String password;
}
2. 登录的Controller层
swagger:
@Api(tags = “LoginController”) : 标注在类
@ApiOperation(value = “登录后返回token”): 标注在方法
package com.jzq.server.controller;
import com.jzq.server.config.result.RespBean;
import com.jzq.server.pojo.AdminLoginParam;
import com.jzq.server.service.IAdminService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@Api(tags = "LoginController")
@RestController
public class LoginController {
@Autowired
private IAdminService adminService;
@ApiOperation(value = "登录后返回token")
@PostMapping("/login")
public RespBean login(AdminLoginParam adminLoginParam, HttpServletRequest request) {
return adminService.login(adminLoginParam.getUsername(), adminLoginParam.getPassword());
}
}
3. 登录的业务层Service
- 接口层
package com.jzq.server.service; import com.jzq.server.config.result.RespBean; import com.jzq.server.pojo.Admin; import com.baomidou.mybatisplus.extension.service.IService; import javax.servlet.http.HttpServletRequest; public interface IAdminService extends IService{ RespBean login(String username, String password, HttpServletRequest request); }
- 接口实现层
注意更新security登录用户对象
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());//第二个参数为口令(密码)不用传
通过SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken)设置
package com.jzq.server.service.impl; import com.jzq.server.config.result.RespBean; import com.jzq.server.config.security.JwtTokenUtil; import com.jzq.server.pojo.Admin; import com.jzq.server.mapper.AdminMapper; import com.jzq.server.service.IAdminService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @Service public class AdminServiceImpl extends ServiceImpl3.2获取用户的信息开发 1.获取用户信息的Controller层(和登录在同一个Controller)implements IAdminService { @Autowired private UserDetailsService userDetailsService; @Autowired private PasswordEncoder passwordEncoder; // 判断密码是否一致 @Autowired private JwtTokenUtil jwtTokenUtil; @Value("${jwt.tokenHead}") // 根据value注解拿到yml中设置的token头 private String tokenHead; @Override public RespBean login(String username, String password, HttpServletRequest request) { // 登录 UserDetails userDetails = userDetailsService.loadUserByUsername(username); if (userDetails==null && !passwordEncoder.matches(password, userDetails.getPassword())) { return RespBean.error("用户名或者密码不正确"); } if (!userDetails.isEnabled()) { return RespBean.error("账号被禁用,请练习管理员"); } // 更新security登录用户对象 UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());//第二个参数为口令(密码)不用传 SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); // 生成token String token = jwtTokenUtil.generateToken(userDetails); Map tokenMap = new HashMap<>(); tokenMap.put("token", token); tokenMap.put("tokenHead", tokenHead); return RespBean.success("登录成功", tokenMap); } }
⭐ Principal对象: principal是我们设置到security中存的全局的用户信息
import *;
@Api(tags = "LoginController")
@RestController
public class LoginController {
@Autowired
private IAdminService adminService;
@ApiOperation(value = "获取当前登录用户的信息")
@GetMapping("/admin/info")
public Admin getAdminInfo(Principal principal) {
// principal是我们设置到security中存的全局的用户信息
if (principal == null) {
return null;
}
String username = principal.getName();
Admin admin = adminService.getAdminByUserName(username);
admin.setPassword(null);
return admin;
}
@ApiOperation(value = "用户退出登录")
@PostMapping("/logout")
private RespBean logout(){
return RespBean.success("注销成功!");
}
}
2. 获取用户信息的Service
- 接口层
RespBean getAdminByUserName(String username);
- 实现层
⭐ adminMapper.selectOne(new QueryWrapper().eq(“username”, username).eq(“enable”, true));
这里是Mybatis-Plus中获取Admin实体类对应数据库表的数据,条件可以链式判断eq(), 两个参数前面的是指定列,后面是判断该列的值
@Service public class AdminServiceImpl extends ServiceImpl3.3 Security的配置类 1. SecurityConfig配置implements IAdminService { @Autowired private UserDetailsService userDetailsService; @Autowired private PasswordEncoder passwordEncoder; // 判断密码是否一致 @Autowired private JwtTokenUtil jwtTokenUtil; @Value("${jwt.tokenHead}") // 根据value注解拿到yml中设置的token头 private String tokenHead; @Autowired private AdminMapper adminMapper; @Override public Admin getAdminByUserName(String username) { return adminMapper.selectOne(new QueryWrapper ().eq("username", username).eq("enable", true)); } }
- 我们主要配置了通过jwt我们无序使用csrf, 以及禁用了cache,使用cookie技术存token。(通过重写configure)
- 添加jwt登录过滤器以及未授权或未登录返回结果
- 配置放行接口
在配置类下方是注入的一些Bean,包括我们自己用到的passwordEncoder、userDetailsService。以及jwt登录过滤与未授权和未登录的结果返回
package com.jzq.server.config.security;
import com.jzq.server.pojo.Admin;
import com.jzq.server.service.IAdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.Filter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private IAdminService adminService;
@Override
public void configure(WebSecurity web) throws Exception {
// 设置放行访问
web.ignoring().antMatchers(
"/login",
"/logout",
"/css
public class JwtAuthencationTokenFilter extends OncePerRequestFilter {
@Value("${jwt.tokenHeader}")
private String tokenHeader;
@Value("${jwt.tokenHead}")
private String tokenHead;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String authHeader = request.getHeader(tokenHeader); // 获取token值
// 存在token (获取的token不为空,且token前面携带的表示是我们设置的标识)
if (authHeader!=null && authHeader.startsWith(tokenHead)){
String authToken = authHeader.substring(tokenHead.length()); // 截取下除了头部标识以后的token
String username = jwtTokenUtil.getUserNameFromToken(authToken); // 通过token就可以拿到用户名(解析荷载部分)
// 看看username存在,但是未登录(就是检测是不是设置在security全局中)
if (username != null && SecurityContextHolder.getContext().getAuthentication()==null) {
// 登录
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
// 验证token是否有效,重新设置用户对象
if (jwtTokenUtil.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
}
// 最后放行
filterChain.doFilter(request,response);
}
}
3. 未授权结果返回
package com.jzq.server.config.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jzq.server.config.result.RespBean;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class RestfulAccessDeniedHandel implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
PrintWriter printWriter = response.getWriter();
RespBean respBean = RespBean.error("权限不足,请联系管理员");
respBean.setCode(403);
printWriter.write(new ObjectMapper().writevalueAsString(respBean));
printWriter.flush(); // 强推到浏览器
printWriter.close();
}
}
4. 未登录或登录失效返回
package com.jzq.server.config.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jzq.server.config.result.RespBean;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Controller
public class RestAuthorizationEnrtyPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
PrintWriter printWriter = response.getWriter();
RespBean respBean = RespBean.error("登录失效,请重新登录");
respBean.setCode(401);
printWriter.write(new ObjectMapper().writevalueAsString(respBean));
printWriter.flush(); // 强推到浏览器
printWriter.close();
}
}
四、Swagger2配置
4.1 pom
io.springfox
springfox-swagger2
2.7.0
com.github.xiaoymin
swagger-bootstrap-ui
1.9.6
4.2 swagger配置类
配置了文档访问地址
以及配置了全局配置Authorization
package com.jzq.server.config.Swagger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.documentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket createRestApi(){
return new Docket(documentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.jzq.server.controller"))
.paths(PathSelectors.any())
.build()
.securityContexts(securityContexts())
.securitySchemes(securitySchemes());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("云e办接口文档")
.description("描述")
.contact(new Contact("jzq", "http:localhost:7777/doc.html", "xxx@xxx.com"))
.build();
}
private List securitySchemes() {
// 设置请求头
List result = new ArrayList<>();
ApiKey apiKey = new ApiKey("Authorization", "Authorization", "Header");
result.add(apiKey);
return result;
}
private List securityContexts() {
// 设置需要登录认证的路径
List result = new ArrayList<>();
result.add(getContextByPath("/test/.*"));
return result;
}
private SecurityContext getContextByPath(String pathRegex) {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex(pathRegex))
.build();
}
private List defaultAuth() {
List result = new ArrayList<>();
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
result.add(new SecurityReference("Authorization", authorizationScopes));
return result;
}
}
例如:



