Swagger简介
前后端分离:vue+Springboot
后端时代:前端只管html+css+js,后端:模板引擎 jsp==>后端主力
前后端分离时代:
后端“控制层、服务层、数据访问层【后端团队】
前端:前端控制层、视图层【前端团队】
伪造后端数据
前后端交互:API
前后端相对独立,松耦合,前后端甚至可以分别部署到不同的服务器上面
交互问题,前后端集成联调?
前端人员和后端人员无法做到协商,尽早解决,导致问题爆发
解决方法:制定一个计划提纲schema,实时更新api,降低集成风险,
早些年:word计划文档,
前后端分离:
前端测试后端接口:
后端提供接口:提供最新消息和改动
Swagger:号称最流行的api框架
RestFul API 文档在线自动生成问题==>API文档与API定义同步更新,
直接可以在线测试,
可以在线测试接口
支持多种语言
在项目中使用Swagger,需要导入jar包:swagger2,swagger-ui
springboot集成swagger
新建一个springboot-web项目
导入依赖
编写一个helloword
默认配置
@Configuration
@EnableSwagger2 //Swagger2
public class SwaggerConfig {
}
访问:http://localhost:8080/swagger-ui.html
得到页面
配置Swagger
Swagger的实例:
Swagger配置bean 的 Dorket
配置扫描接口
Docket.select()
//看源码学习
@Configuration
@EnableSwagger2 //Swagger2
public class SwaggerConfig {
//配置swagger的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//RequestHandlerSelectors配置要扫描的接口
//basePackage 扫描指定包 .basePackage("com.ty.controller")
//none 全部不扫描
//any 扫描所有接口
//withMethodAnnotation 扫描指定方法上的方法 .withClassAnnotation(RequestMapping.class)
//withClassAnnotation 扫描指定类上的方法 .withClassAnnotation(RestController.class))
.apis(RequestHandlerSelectors.basePackage("com.ty.controller"))
//paths() 过滤路径
.paths(PathSelectors.ant("/ty/**"))
.build();
}
//配置swagger的apiInfo信息
private ApiInfo apiInfo(){
//这里爆红,拿到源码的信息 指作者信息
Contact DEFAULT_CONTACT = new Contact("ty",
"https://editor.youkuaiyun.com/md?not_checkout=1&articleId=109269811",
"123456789@qq.com");
return new ApiInfo("ty 的api文档",
"出关为学,不成不还",
"V1.0",
"https://editor.youkuaiyun.com/md?not_checkout=1&articleId=109269811",
DEFAULT_CONTACT,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0", new ArrayList());
}
}
配置API文档分组
.groupName(“ty”)
如何进行多分组:多写一个docket
实体类配置:
@RestController
public class HelloController {
@GetMapping(value = “/hello”)
public String hello(){
return “hello”;
}
@PostMapping(value = "/user")
public User user(){
return new User();
}
//给接口加注释,给方法加注释
@ApiOperation("hello控制类")
@GetMapping("/hello2")
public String hello2(@ApiParam("用户名") String username){
return "hello"+username;
}
@ApiOperation("post控制类")
@PostMapping("/hello3")
public User post(@ApiParam("用户") User user){
return user;
}
}
@ApiModel(“用户实体类”)
public class User {
@ApiModelProperty(“用户名”)
public String username;
@ApiModelProperty(“密码”)
public String password;
}
通过swagger给一些比较难理解的属性或者接口添加注释信息
接口文档实时更新
可以在线测试
在唯一要注意的点:发布的时候关闭接口文档
任务
异步任务
需要在启动类上面添加配置
/开启某任务 某功能 Enable xxx 这里开启异步任务
@EnableAsync
创建一个服务类,告诉程序这个3秒之后执行
//告诉spring这是一个异步任务
@Async
public void hello(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("数据处理中。。。。");
}
创建一个控制器,三秒之后输出信息
@RestController
public class AsyncController {
@Autowired
AsyncService asyncService;
@GetMapping("/hello")
public String hello(){
asyncService.hello();//停止三秒 -- 转圈
return "ok";
}
}
邮件任务
编写配置application.properties
#配置qq名字
spring.mail.username=2911209994@qq.com
#配置授权码 qq设置获取 用自己的qq邮箱,
spring.mail.password=vqzxhturqlszdhce
#主机
spring.mail.host=smtp.qq.com
#开启加密授权认证
spring.mail.properties.mail.smtp.ssl.enable=true
编写测试类
@SpringBootTest
class Springboot14AsyncApplicationTests {
@Autowired
JavaMailSenderImpl mailSender;
@Test
void contextLoads() {
//一个简单的邮件
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setSubject("您好,悠悠人力资源人事调配通知!!!");
mailMessage.setText("您已成功从技术部调换到人事部,请与明天下午到人事部门报道,地点:xx集团三楼人事部办公室1");
mailMessage.setTo("2911209994@qq.com");
mailMessage.setFrom("2911209994@qq.com");
mailSender.send(mailMessage);
}
//复杂邮件发送
@Test
public void test(){
//一个复杂的邮件
MimeMessage mimeMessage = mailSender.createMimeMessage();
try {
//组装
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
//正文
helper.setSubject("您好,悠悠人力资源人事调配通知!!!");
helper.setText("<p style='color:red'>您已成功从技术部调换到人事部,请与明天下午到人事部门报道," +
"地点:xx集团三楼人事部办公室1,下面是我部门的整体结构</p>",true);
//附件 图片 可以是绝对地址
helper.addAttachment("1.png",new File("C:\\Users\\taoying147258zlx\\Desktop\\1.png"));
helper.addAttachment("2.png",new File("C:\\Users\\taoying147258zlx\\Desktop\\1.png"));
//接收方 发送方
helper.setTo("2911209994@qq.com");
helper.setFrom("2911209994@qq.com");
} catch (MessagingException e) {
e.printStackTrace();
}
mailSender.send(mimeMessage);
}
@Test
public void send(){
sendMail(true,"主题","<h1>正文</h1>","图片的名字", new File("C:\\Users\\taoying147258zlx\\Desktop\\1.png"),
"2911209994@qq.com","2911209994@qq.com");
}
//封装成一个工具类 方便以后使用,
public void sendMail(Boolean html,String subject,String text,String phone,File file,String to,String from){
//一个复杂的邮件
MimeMessage mimeMessage = mailSender.createMimeMessage();
try {
//组装
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
//正文
helper.setSubject(subject);
helper.setText(text,html);
//附件 图片 可以是绝对地址
helper.addAttachment(phone,file);
//接收方 发送方
helper.setTo(to);
helper.setFrom(from);
} catch (MessagingException e) {
e.printStackTrace();
}
mailSender.send(mimeMessage);
}
}
定时任务
在启动类中加入配置
@EnableScheduling //开启定时任务注解
编写定时任务类
@Service
public class ScheduledService {
//编写一个测试类 在一个特定时间内执行一个方法 timer
//cron //秒 分 时 日 月 周几~ 0 * * * * * 0-7 问好表示不知道?
/*
* 30 29 9 * * ? 固定格式 9点29分30秒多的时候执行程序
* 30 0/5 9,18 * * ? 固定格式 9点和18点每隔五分钟执行一次程序多的时候执行程序
* 0 15 10 ? * ? 每个月的十点十五分执行一次
* */
@Scheduled(cron = "30 29 9 * * ?")
public void hello() {
System.out.println("hello,执行了该任务了。。。。");
}
}
关键接口:
taskExecutor任务执行者 TaskScheduler任务调度器
涉及到的注解:@EableXXX开启某功能注解 使用定时任务Schedule 什么时候执行
Cron 表达式
SpringBoot整合
Springboot操作数据:spring-data jpa jdbc mongodb redis
SpringData也是和springboot齐名的项目
说明在springboot2.x开始之后 原来的jedis替换成了lettuce
jeids:采用直连,多个线程操作的话,是不安全的,如果想要避免不安全的,要使用jedis、pool连接池,类似BIO
lettuce:采用netty,实例可以在多个线程中共享,不存在不安全的情况,可以减少线程的数量,更像NIO模式
源码分析:打开源码的方式:打开External Libaries,搜索autocofigure,打开配置jar包下面的META-INF下的spring.facties,ctrl+f搜索rediRedisAutoConfiguration,ctrl+鼠标左键打开源码,查看注解打开RedisProperties,找到源码
@Bean
@ConditionalOnMissingBean( //可以自定义一个template替换
name = {"redisTemplate"}
)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
//默认的RedisTemplate,没有更多设置,redis对象需要序列化
//map都是泛型Object, Object的类型,需要强转
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean //reids属于常常使用的类型,所以单独提出的一个bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
整合测试
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.添加配置
配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
3.测试 注意:这里需要安装了redis 并且redis的服务必须开启
@SpringBootTest
class Springboot15RedisApplicationTests {
@Autowired
RedisTemplate redisTemplate;
@Test
void contextLoads() {
//redisTemplate 操作不同的数据类型,api和指令类似
//opsForValue 操作字符串 类似于string
//opsForList 操作list
//除了基本的操作,常用的方法也可以通过他来完成,比如事务。crud
//获取连接
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//connection.flushDb();
// connection.flushAll();
redisTemplate.opsForValue().set("ty","study");
redisTemplate.opsForValue().set("xx","学习");
System.out.println(redisTemplate.opsForValue().get("ty"));
System.out.println(redisTemplate.opsForValue().get("xx"));
}
}
序列化
自定义redisTemplable
@Configuration
public class RedisConfig {
/**
* 编写自定义的 redisTemplate
* 这是一个比较固定的模板 企业中直接使用
*/
@Bean
@SuppressWarnings(“all”)
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
// 为了开发方便,直接使用<String, Object>
RedisTemplate<String, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
// Json 配置序列化
// 使用 jackson 解析任意的对象
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
// 使用 objectMapper 进行转义
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// String 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key 采用 String 的序列化方式
template.setKeySerializer(stringRedisSerializer);
// Hash 的 key 采用 String 的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value 采用 jackson 的序列化方式
template.setValueSerializer(jackson2JsonRedisSerializer);
// Hash 的 value 采用 jackson 的序列化方式
template.setHashValueSerializer(jackson2JsonRedisSerializer);
// 把所有的配置 set 进 template
template.afterPropertiesSet();
return template;
}
}
视频学习地址:https://www.bilibili.com/video/BV1PE411i7CV?p=56
集合作者笔记:百度搜索狂神说Springboot