Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。
前后端分离
-
前端 -> 前端控制层、视图层
-
后端 -> 后端控制层、服务层、数据访问层
-
前后端通过API进行交互
-
前后端相对独立且松耦合
-
接口的文档在线自动生成。
-
功能测试。
-
Swagger-tools:提供各种与Swagger进行集成和交互的工具。例如模式检验、Swagger 1.2文档转换成Swagger 2.0文档等功能。
-
Swagger-core: 用于Java/Scala的的Swagger实现。与JAX-RS(Jersey、Resteasy、CXF...)、Servlets和Play框架进行集成。
-
Swagger-js: 用于Javascript的Swagger实现。
-
Swagger-node-express: Swagger模块,用于node.js的Express web应用框架。
-
Swagger-ui:一个无依赖的HTML、JS和CSS集合,可以为Swagger兼容API动态生成优雅文档。
-
Swagger-codegen:一个模板驱动引擎,通过分析用户Swagger资源声明以各种语言生成客户端代码。
新建一个spirngboot项目,勾选组件时勾选Spring-Web
导入Swagger依赖
编写HelloController
在主程序同级目录下新建controller包,其中新建HelloController类
启动主程序
编写Swagger配置类
在主程序同级目录下新建config包,其中新建SwaggerConfig配置类
-
用@Configuration注解注明这是配置类
-
同时用@EnableSwagger2注解开启Swagger2
测试进入Sawgger页面
重启主程序,访问localhost:8080/swagger-ui.html
5、配置Swagger API信息Swagger实例Bean是Docket,所以通过配置Docket实例来配置Swaggger。
通过配置ApiInfo类的信息然后传入Docket的bean实例
整体代码SwaggerConfig.java
重新访问localhost:8080/swagger-ui.html,可以看到Swagger信息已经变更成我们定义的信息
6、配置Swagger自定义扫描接口在这个ui界面中,可以看到扫描了两个controller接口,上面的是默认的controller接口,下面是我们自己写的hellocontroller
构建Docket时通过select()方法配置怎么扫描接口。
5、配置Swagger开关通过Docket对象的.enable方法来配置swagger是否启动
开发环境和正式环境时切换
首先在resources目录下新建两种springboot配置文件:
开发环境:application-dev.properties
server.port=8081
正式环境:application-pro.properties
server.port=8082
然后在主配置文件application.properties中激活开发环境
spring.profiles.active=dev
然后在 SwaggerConfig 中的 docket() 方法中添加代码:
-
首先给该方法传一个参数Environment
Environment environment
-
首先设置药配置的Swagger环境:这里可以添加多个环境
Profiles profiles = Profiles.of("dev", "test");
-
然后通过environment.acceptsProfiles方法判断是否处在上一步设定的dev/test环境中,返回一个boolean的值,我们用flag接收
boolean flag = environment.acceptsProfiles(profiles);
-
然后修改enable中的参数为flag,即通过flag来判断是否开启Swagger
.enable(flag)//通过flag判断是否开启
完整代码
然后启动主程序测试:由于激活了dev开发环境,所以访问localhost:8081/swagger-ui.html
成功开启swagger,如果我们修改主配置文件,激活pro
spring.profiles.active=pro
再次重启主程序测试,访问端口8082对应的地址localhost:8082/swagger-ui.html
6、配置API文档分组 (1)、设置默认组名页面里默认只有一个组且组名为default
在docket通过.groupName中设置组名
重启测试,可以看到组名已更改
(2)、配置多个组一个Docket实例就对应着一个组,因此我们配置多个docket就对应着多个组
新增两个Docket
再次重启测试
7、配置Model实体类新建实体类
在主程序同级目录下新建pojo包,其中新建User实体类
编写对应请求接口
在HelloController中新增一个方法返回实体类的实例对象即可映射到实体项中
启动测试
常用注解
-
@ApiModel为类添加注释
-
@ApiModelProperty为类属性添加注释
同样可以在Controller类和其中的方法上添加相应的注解
重启测试,即可以看到注释信息
同样可以在Controller类和其中的方法上添加相应的注解
重启即可看到对应的注解
8、测试Swagger的使用 (1)、测试传参在HelloController中新增一个方法,参数为username,可以用@ApiParam给该参数添加注解
(2)、测试错误在HelloController中新增一个方法,参数为User,可以用@ApiParam给该参数添加注解
二、任务 1、异步任务异步(async)是相对于同步(sync)来说的,简单理解,同步是串行的,异步是并行的。
在想要异步执行的方法上加上@Async注解,在controller上加上@EnableAsync,即可。注意,这里的异步方法,只能在自身之外调用,在本类调用是无效的。
controller层
serviceceng
TaskApplication,java
测试,网页瞬间响应,后台代码依旧延迟3秒执行
2、定时任务Spring为我们提供了异步执行任务调度的方式,提供了两个接口。
-
TaskExecutor接口
-
TaskScheduler接口
两个注解:
-
@EnableScheduling
-
@Scheduled
创建一个ScheduledService
这里写完定时任务之后,我们需要在主程序上增加@EnableScheduling 开启定时任务功能
常见的cron表达式
-
0/2 * * * * ? 表示每2秒 执行任务
-
0 0/2 * * * ? 表示每2分钟 执行任务
-
0 0 2 1 * ? 表示在每月的1日的凌晨2点调整任务
-
0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业
-
0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作
-
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
-
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
-
0 0 12 ? * WED 表示每个星期三中午12点
-
0 0 12 * * ? 每天中午12点触发
-
0 15 10 ? * * 每天上午10:15触发
-
0 15 10 * * ? 每天上午10:15触发
-
0 15 10 * * ? 每天上午10:15触发
-
0 15 10 * * ? 2005 2005年的每天上午10:15触发
-
0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
-
0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
-
0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
-
0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
-
0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
-
0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
-
0 15 10 15 * ? 每月15日上午10:15触发
-
0 15 10 L * ? 每月最后一日的上午10:15触发
-
0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
-
0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
-
0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
操作步骤:
-
邮件发送需要引入spring-boot-start-mail
-
SpringBoot 自动配置MailSenderAutoConfiguration
-
定义MailProperties内容,配置在application.yml中
-
自动装配JavaMailSender
-
测试邮件发送
引入pom依赖
配置文件application.properties:
Spring单元测试
三、Dubbo和Zookeeper集成 1、分布式理论分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。
作用:提供服务自动注册,自动发现等高效服务治理方案
2、运行原理-
启动容器,相当于在启动Dubbo的Provider
-
启动后回曲注册中心进行注册,注册所有可以提供的服务列表
-
在Consumer启动后会去Registry中获取服务列表和Provider的地址,进行丁云
-
当Provider有修改后,注册中心会把消息推送给Consummer,使用了观察者设计模式
-
根据获取到的Provider地址,真实调用Provider中的功能,在consummer方使用了代理设计模式,创建了一个Provider方类的一个代理对象。通过代理对象获取Provider中的真实功能,起到保护Provider真实功能的作用。
-
Consumer和Provider每隔一分钟会向Monitor发送统计信息,统计信息包括访问次数,频率等。
-
Zookeeper
Zookeeper:分布式协调组件,本质上是一个软件
优点:支持网络集群
缺点:稳定性受限于zookeeper
-
redis注册中心
优点:性能高(内存型数据库)
缺点:对服务器的环境要求较高
-
Multicast
优点:面中心化,不需要额外安装注册中心
缺点:建议同机房(局域网)内使用
-
Simple
适用于测试环境,不支持集群
四、SpringSecurity 1、简介SpringSecurity 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。
spring security 的核心功能:
-
认证
-
授权
-
攻击保护
四种权限控制方式:
-
表达式控制 URL 路径权限
-
表达式控制方法权限
-
使用过滤注解
-
动态权限
SpringSecurity依赖:
编写SpringSecurity配置类
定制请求的授权规则
测试,除了首页其他页面都进不去了,所以在configure()方法中加入以下配置,开启自动配置的登录功能
定义认证规则,重写configure(AuthenticationManagerBuilder auth)方法,但要将前端传过来的密码进行某种方式加密,否则就无法登录,修改代码,spring security 官方推荐的是使用bcrypt加密方式。
五、Shiro 1、简介Shiro不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。
Shiro 三大要素
-
subject -> ShiroFilterFactoryBean
-
securityManager -> DefaultWebSecurityManager
-
realm
实际操作中对象创建的顺序 : realm -> securityManager -> subject
2、创建Shiro项目创建普通Maven项目,导入pom依赖
将ini静态资源导出资源
log4j.properties
shiro.ini文件
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Tutorial {
private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class);
public static void main(String[] args) {
log.info("My First Apache Shiro Application"); System.exit(0);
}
}
Quickstart.java
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Quickstart {
private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
public static void main(String[] args) {
Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
session.setAttribute("someKey", "aValue");
String value = (String) session.getAttribute("someKey");
if (value.equals("aValue")) {
log.info("Retrieved the correct value! [" + value + "]");
}
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
token.setRememberMe(true);
try {
currentUser.login(token);
} catch (UnknownAccountException uae) {
log.info("There is no user with username of " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
log.info("Password for account " + token.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {
log.info("The account for username " + token.getPrincipal() + " is locked. " +
"Please contact your administrator to unlock it.");
}
catch (AuthenticationException ae) {
}
}
log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
if (currentUser.hasRole("schwartz")) {
log.info("May the Schwartz be with you!");
} else {
log.info("Hello, mere mortal.");
}
if (currentUser.isPermitted("lightsaber:wield")) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
if (currentUser.isPermitted("winnebago:drive:eagle5")) {
log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +
"Here are the keys - have fun!");
} else {
log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
}
currentUser.logout();
System.exit(0);
}
}
运行
3、分析Shiro通过 SecurityUtils 获取当前执行的用户 Subject
通过 当前用户拿到 Session
用 Session 存值取值
判断用户是否被认证
打印其标识主体
注销
4、SpringBoot 集成 Shiro新建一个 springboot 模块,导入 SpringBoot 和 Shiro 整合包的依赖



