第105天学习打卡(SpringBoot shiro整合thymeleaf Swagger SpringBoot集成Swagger 配置Swagger Swagger配置扫描接口)
shiro 整合thymeleaf
在pom.xml中整合shiro-thymeleaf
<!--shiro-thymeleaf-->
<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
添加的代码:
Subject currentSubject = SecurityUtils.getSubject();
Session session = currentSubject.getSession();
session.setAttribute("loginUser",user);
完整代码:UserRealm.java
package com.kuang.config;
import com.kuang.pojo.User;
import com.kuang.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
//自定义的 UserRealm extends AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了=>授权doGetAuthorizationInfo");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermission("user:add");//无论什么用户等进来都会走这个方法
//拿到当前登录的这个对象
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();//拿到user对象
//设置当前用户的权限
info.addStringPermission(currentUser.getPerms());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了=>认证doGetAuthenticationInfo");
// //用户名,密码 数据库中取
// String name = "root";
// String password = "123456";
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//连接真实数据库
User user = userService.queryUserByName(userToken.getUsername());
if(user==null){
//没有这个人
return null; //爆出异常UnknownAccountException
}
Subject currentSubject = SecurityUtils.getSubject();
Session session = currentSubject.getSession();
session.setAttribute("loginUser",user);
// if (!userToken.getUsername().equals(name)){
// return null;//抛出异常 UnknownAccountException 用户名不存在
//
// }
//可以加密:MD5 MD5盐值加密 MD5不可逆
//密码认证,shiro做 加密
return new SimpleAuthenticationInfo(user,user.getPwd(),"");
}
}
ShiroConfig.java
package com.kuang.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
//ShiroFilterFactory 第三步
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加shiro的内置过滤器
/*
anon : 无需认证就可以访问
authc:必须认证了才可能访问
user : 必须拥有 记住我,功能才能用
perms:拥有对某个资源的权限才能访问
role:拥有某个角色权限才能访问
*/
//拦截
Map<String, String> filterMap = new LinkedHashMap<>();
//授权,正常情况下,没有授权会跳转到未授权页面
filterMap.put("/user/add","perms[user:add]"); //是user用户 还必须有add权限才可以访问
filterMap.put("/user/update","perms[user:update]");
// filterMap.put("/user/add","authc"); // 方法1
// filterMap.put("/user/update","authc");
//把上面两行代码合成一个
filterMap.put("/user/*","authc");
bean.setFilterChainDefinitionMap(filterMap);
//设置登录的请求
bean.setLoginUrl("/toLogin");
//未授权页面
bean.setUnauthorizedUrl("/noauth");
return bean;
}
//DefaultWebSecurityManager 第二步
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建 realm对象, 需要自定义 第一步
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
//整合ShiroDialect:用来整合shiro thymeleaf
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
}
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<!--从session中判断值-->
<div th:if="${session.loginUser==null}">
<a th:href="@{/toLogin}">登录</a>
</div>
<p th:text="${msg}"></p>
<hr>
<div shiro:hasPermission="user:add">
<a th:href="@{/user/add}">add</a>
</div>
<div shiro:hasPermission="user:update">
<a th:href="@{/user/update}">update</a>
</div>
</body>
</html>
下载的开源项目网址:https://github.com/WinterChenS/my-site
连接数据库:

jdbc:mysql://localhost:3306/?serverTimezone=GMT
Swagger
学习目标:
- 了解Swagger的作用和概念
- 了解前后端分离
- 在SpringBoot中集成Swagger
Swagger简介
前后端分离
Vue + SpringBoot
后端时代:前端只用管理静态页面;html==>后端。模板引擎JSP=>后端是主力。
前后端分离时代:
-
后端:后端控制层, 服务层,数据访问层
-
前端:前端控制层,视图层
- 伪造后端数据,json交互。已经存在了,不需要后端,前端工程依旧能跑出来。
-
前后端如何交互?===> API
-
前后端相对独立,松耦合
-
前后端甚至可以部署在不同的服务器上;
产生一个问题:
- 前后端集成联调,前端人员和后端人员无法做到,及时协商。尽早解决,最终导致问题集中爆发;
解决方案:
- 首先指定schema[计划的提纲],实时更新最新API,降低集成的风险
- 早些年:制定word计划文档;
- 前后端分离:
- 前端测试后端接口:postman https://www.postman.com/
- 后端提供接口,需要实时更新最新的消息及改动。
Swagger
- 号称世界上最流行的APi框架
- RestFul Api文档在线自动生成工具=>Api文档与API定义同步更新。
- 直接运行,可以在线测试API接口;
- 支持多种语言(Java php)
官网地址:https://swagger.io/
在项目中使用Swagger需要springbox
- swagger2
- ui
SpringBoot集成Swagger
1.新建一个SpringBoot-web项目
2.导入相关依赖
注意点:导入最新的3.0.0版本访问不了页面,需要降级
<dependencies>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
3.编写一个Hello工程
package com.kuang.swagger.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController //由于我们没有页面所有要给他返回一个字符串
public class HelloController {
@RequestMapping(value = "/hello")
public String hello(){
return "hello";
}
}
**出现的错误: Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2021-04-23 19:25:08.794 ERROR 14588 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : **
一般出现这个错误的原因是:另外还存在一个项目在运行 ,把另外一个项目关掉即可。
4.配置Swagger==>Config
package com.kuang.swagger.config;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration //相当于@Component
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
}
5.测试访问页面:http://localhost:8080/swagger-ui.html

配置Swagger
Swagger的bean实例Docket;
package com.kuang.swagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
@Configuration //相当于@Component
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}
//配置Swagger信息 = apiInfo
private ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("秦疆", "https://blog.kuangstudy.com/", "24736743@qq.com");
return new ApiInfo("狂神的SwaggerAPI文档",
"即使再小的帆也能远航",
"v1.0", "https://blog.kuangstudy.com",
contact, "Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}

这个拥有所有的扫描接口:

Swagger配置扫描接口
package com.kuang.swagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
@Configuration //相当于@Component
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//RequestHandlerSelectors 配置要扫描接口的方式
//basePackage指定要扫描的包
.apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
.build();
}
//配置Swagger信息 = apiInfo
private ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("秦疆", "https://blog.kuangstudy.com/", "24736743@qq.com");
return new ApiInfo("狂神的SwaggerAPI文档",
"即使再小的帆也能远航",
"v1.0", "https://blog.kuangstudy.com",
contact, "Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}

package com.kuang.swagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
@Configuration //相当于@Component
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//RequestHandlerSelectors 配置要扫描接口的方式
//basePackage指定要扫描的包
//any 扫描全部 apis(RequestHandlerSelectors.any())
//none:都不扫描 apis(RequestHandlerSelectors.none())
//withClassAnnotation():扫描类上的注解 apis(RequestHandlerSelectors.withClassAnnotation()) 参数是一个注解的反射对象
//withMethodAnnotation 扫描方法上的注解 apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))
.apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
//paths()过滤什么路径
.paths(PathSelectors.ant("/kuang/**"))
.build();
}
//配置Swagger信息 = apiInfo
private ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("秦疆", "https://blog.kuangstudy.com/", "24736743@qq.com");
return new ApiInfo("狂神的SwaggerAPI文档",
"即使再小的帆也能远航",
"v1.0", "https://blog.kuangstudy.com",
contact, "Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}

配置是否启动Swagger
package com.kuang.swagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
@Configuration //相当于@Component
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(false) //enable是否启动swagger,如果为false,则swagger不能在浏览器中访问
//select apis build 是一套的
.select()
.apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
//paths()过滤什么路径
//.paths(PathSelectors.ant("/kuang/**"))
.build();
}
//配置Swagger信息 = apiInfo
private ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("秦疆", "https://blog.kuangstudy.com/", "24736743@qq.com");
return new ApiInfo("狂神的SwaggerAPI文档",
"即使再小的帆也能远航",
"v1.0", "https://blog.kuangstudy.com",
contact, "Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}

只希望我的Swagger在生产环境中使用,在发布的时候不使用?
- 判断是不是生产环境 flag = false
- 注入enble(flag)
SwaggerConfig.java
package com.kuang.swagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
@Configuration //相当于@Component
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(Environment environment){
//设置要显示的Swagger环境
Profiles profiles = Profiles.of("dev","test");
//获取项目环境
//通过environment.acceptsProfiles() 判断是否处在自己设定的环境当中
boolean flag = environment.acceptsProfiles(profiles);
System.out.println(flag);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(flag) //enable是否启动swagger,如果为false,则swagger不能在浏览器中访问
//select apis build 是一套的
.select()
.apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
//paths()过滤什么路径
//.paths(PathSelectors.ant("/kuang/**"))
.build();
}
//配置Swagger信息 = apiInfo
private ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("秦疆", "https://blog.kuangstudy.com/", "24736743@qq.com");
return new ApiInfo("狂神的SwaggerAPI文档",
"即使再小的帆也能远航",
"v1.0", "https://blog.kuangstudy.com",
contact, "Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}
application.properties
spring.profiles.active=dev
application-dev.properties
server.port=8081
application-pro.properties
server.port=8082


B站学习网址:【狂神说Java】SpringBoot最新教程IDEA版通俗易懂_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

浙公网安备 33010602011771号