[黑马程序员SpringBoot2]——开发实用篇3

news2024/11/10 13:00:51

目录:

  1. jetcache远程缓存方案
  2. jetcache本地缓存方案
  3. jetcache方法缓存
  4. j2cache基本操作
  5. springboot整合quartz​​​​​​​
  6. springboot整合task
  7. 发送简单邮件
  8. 发送多部件邮件
  9. 消息简介
  10. 购物订单案例-发送短信
  11. ActiveMQ安装
  12. springboot整合ActiveMQ
  13. RabbitMQ安装
  14. springboot整合RabbitMQ(direct模式)
  15. springboot整合RabbitMQ(topic模式)
  16. RocketMQ安装
  17. springboot整合RockeMQ
  18. Kafka安装
  19. springboot整合Kafka
  20. 监控的意义
  21. SpringBootAdmin
  22. actuator
  23. info端点指标控制
  24. health端点指标控制
  25. metrics端点指标控制
  26. ​​​​​​​自定义端点

1.jetcache远程缓存方案

  • jetCache对SpningCache进行了封装,在原有功能基础上实现了多级缓存、缓存统计、自动刷新、异步调用、数据报表等功能
  • jetcache设定了本地缓存与远程缓存的多级缓存解决方案
  • 本地缓存(local)
    • LlinkedHashMap
    • Caffeine
  • 远程缓存(remote)
    • Redis
    • Tair

加入jetcache坐标

配置远程缓存必要属性

配置本地缓存必要属性

配置范例

配置属性说明

开启jetcache注解支持

声明缓存对象

操作缓存

代码示例:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>sprintboot_20_jetcache</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sprintboot_20_jetcache</name>
    <description>sprintboot_20_jetcache</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alicp.jetcache</groupId>
            <artifactId>jetcache-starter-redis</artifactId>
            <version>2.6.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.yml

server:
  port: 8080

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3308/test_db
      username: root
      password: 666666

jetcache:
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

BookController.class

package com.example.springboot_20_jetcache.controller;

import com.example.springboot_20_jetcache.domain.Book;
import com.example.springboot_20_jetcache.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService;

    @GetMapping("{id}")
    public Book getById(@PathVariable Integer id) {
        return bookService.getById(id);
    }

    @PostMapping
    public boolean save(@RequestBody Book book) {
        return bookService.save(book);
    }

    @PutMapping
    public boolean update(@RequestBody Book book) {
        return bookService.update(book);
    }

    @DeleteMapping("{id}")
    public boolean delete(@PathVariable Integer id) {
        return bookService.delete(id);
    }

    @GetMapping
    public List<Book> getAll() {
        return bookService.getAll();
    }
}

SMSCodeController.class

package com.example.springboot_20_jetcache.controller;

import com.example.springboot_20_jetcache.domain.SMSCode;
import com.example.springboot_20_jetcache.service.SMSCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/sms")
public class SMSCodeController {

    @Autowired
    private SMSCodeService smsCodeService;

    @GetMapping
    public String getCode(String tele) {
        String code = smsCodeService.sendCodeToSMS(tele);
        return code;
    }

    @PostMapping
    public boolean checkCode(SMSCode smsCode) {
        return smsCodeService.checkCode(smsCode);
    }
}

BookDao.interface

package com.example.springboot_20_jetcache.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springboot_20_jetcache.domain.Book;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BookDao extends BaseMapper<Book> {
}

Book.class

package com.example.springboot_20_jetcache.domain;

import lombok.Data;

@Data
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;
}

SMSCode.class

package com.example.springboot_20_jetcache.domain;

import lombok.Data;

@Data
public class SMSCode {
    private String tele;
    private String code;
}

BookServiceImpl.class

package com.example.springboot_20_jetcache.service.impl;

import com.example.springboot_20_jetcache.dao.BookDao;
import com.example.springboot_20_jetcache.domain.Book;
import com.example.springboot_20_jetcache.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    @Override
    public Book getById(Integer id) {
        Book queryBook = bookDao.selectById(id);
        return queryBook;
    }


    @Override
    public boolean save(Book book) {
        return bookDao.insert(book) > 0;
    }

    @Override
    public boolean update(Book book) {
        return bookDao.updateById(book) > 0;
    }

    @Override
    public boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }

    @Override
    public List<Book> getAll() {
        return bookDao.selectList(null);
    }
}

SMSCodeServiceImpl.class

package com.example.springboot_20_jetcache.service.impl;

import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CreateCache;
import com.example.springboot_20_jetcache.domain.SMSCode;
import com.example.springboot_20_jetcache.service.SMSCodeService;
import com.example.springboot_20_jetcache.utils.CodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils codeUtils;

    @CreateCache(name = "jetCache", expire = 10, timeUnit = TimeUnit.SECONDS)
    private Cache<String, String> jetCache;

    @CreateCache(area = "sms", name = "jetCache2", expire = 10, timeUnit = TimeUnit.SECONDS)
    private Cache<String, String> jetCache2;

    @Override
    public String sendCodeToSMS(String tele) {
        String code = codeUtils.generator(tele);
        jetCache.put(tele, code);
        return code;
    }

    @Override
    public boolean checkCode(SMSCode smsCode) {
        String code = jetCache.get(smsCode.getTele());
        return smsCode.getCode().equals(code);
    }
}

BookService.interface

package com.example.springboot_20_jetcache.service;


import com.example.springboot_20_jetcache.domain.Book;

import java.util.List;

public interface BookService {
    public boolean save(Book book);

    public Book getById(Integer id);

    public boolean update(Book book);

    public boolean delete(Integer id);

    public List<Book> getAll();
}

SMSCodeService.interface

package com.example.springboot_20_jetcache.service;

import com.example.springboot_20_jetcache.domain.SMSCode;

public interface SMSCodeService {
    public String sendCodeToSMS(String tele);

    public boolean checkCode(SMSCode smsCode);
}

CodeUtils.class

package com.example.springboot_20_jetcache.utils;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class CodeUtils {

    private String[] patch = {"000000", "00000", "0000", "000", "00", "0", ""};

    public String generator(String tele) {
        int hash = tele.hashCode();
        int encryption = 20206666;
        long result = hash ^ encryption;
        long nowTime = System.currentTimeMillis();
        result = result ^ nowTime;
        long code = result % 1000000;
        code = code < 0 ? -code : code;
        String codeStr = code + "";
        int len = codeStr.length();

        return patch[len] + codeStr;
    }


    @Cacheable(value = "smsCode", key = "#tele")
    public String get(String tele) {
        return null;
    }

    public static void main(String[] args) {
        System.out.println(new CodeUtils().generator("15033657967"));
    }
}

Springboot20JetcacheApplication.class

package com.example.springboot_20_jetcache;

import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableCreateCacheAnnotation
public class Springboot20JetcacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot20JetcacheApplication.class, args);
    }

}

2.jetcache本地缓存方案

application.yml

server:
  port: 8080

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3308/test_db
      username: root
      password: 666666

jetcache:
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

SMSCodeServiceImpl.class

package com.example.springboot_20_jetcache.service.impl;

import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.CreateCache;
import com.example.springboot_20_jetcache.domain.SMSCode;
import com.example.springboot_20_jetcache.service.SMSCodeService;
import com.example.springboot_20_jetcache.utils.CodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils codeUtils;

//    @CreateCache(name = "jetCache", expire = 10, timeUnit = TimeUnit.SECONDS)
//    private Cache<String, String> jetCache;
//
//    @CreateCache(area = "sms", name = "jetCache2", expire = 10, timeUnit = TimeUnit.SECONDS)
//    private Cache<String, String> jetCache2;


    @CreateCache(name = "jetCache", expire = 1000, timeUnit = TimeUnit.SECONDS,cacheType = CacheType.LOCAL)
    private Cache<String, String> jetCache;

    @Override
    public String sendCodeToSMS(String tele) {
        String code = codeUtils.generator(tele);
        jetCache.put(tele, code);
        return code;
    }

    @Override
    public boolean checkCode(SMSCode smsCode) {
        String code = jetCache.get(smsCode.getTele());
        return smsCode.getCode().equals(code);
    }
}

3.jetcache方法缓存

启用方法注解

使用方法注解操作缓存

 

缓存对象必须保障可序列化

 

查看缓存统计报告

application.yml

server:
  port: 8080

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3308/test_db
      username: root
      password: 666666

jetcache:
  statIntervalMinutes: 1
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      keyConvertor: fastjson
      valueEncode: java
      valueDecode: java
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

BookServiceImpl.class

package com.example.springboot_20_jetcache.service.impl;

import com.alicp.jetcache.anno.*;
import com.example.springboot_20_jetcache.dao.BookDao;
import com.example.springboot_20_jetcache.domain.Book;
import com.example.springboot_20_jetcache.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    @Override
    @Cached(area = "default", name = "book", key = "#id", expire = 3600, cacheType = CacheType.REMOTE)
    //    @CacheRefresh(refresh = 5)
    public Book getById(Integer id) {
        Book queryBook = bookDao.selectById(id);
        return queryBook;
    }


    @Override
    public boolean save(Book book) {
        return bookDao.insert(book) > 0;
    }

    @Override
    @CacheUpdate(name = "book", key = "#book.id", value = "#book")
    public boolean update(Book book) {
        return bookDao.updateById(book) > 0;
    }

    @Override
    @CacheInvalidate(name = "book", key = "#id")
    public boolean delete(Integer id) {
        return bookDao.deleteById(id) > 0;
    }

    @Override
    public List<Book> getAll() {
        return bookDao.selectList(null);
    }
}

4.j2cache基本操作

  • j2cache是一个缓存整合框架,可以提供缓存的整合方案,使各种缓存搭配使用,自身不提供缓存功能
  • 基于ehcache + nedis.进行整合

加入j2cache坐标,加入整合缓存的坐标

配置使用j2cache (application.yml)

配置─级缓存与二级缓存以及一级缓存数据到二级缓存的发送方式 (j2cache.properties)

设置使用缓存

 

5.springboot整合quartz

  • 定时任务是企业级应用中的常见操作
    • 年度报表
    • 缓存统计报告
  • 市面上流行的定时任务技术
    • Quartz
    • Spring Task

相关概念

  • 工作 (Job)∶用于定义具体执行的工作
  • 工作明细(JobDetail):用于描述定时工作相关的信息
  • 触发器(Trigger)∶用于描述触发工作的规则,通常使用cron表达式定义调度规则
  • 调度器(Scheduler):描述了工作明细与触发器的对应关系

导入SpringBoot整合quartz的坐标

定义具体要执行的任务,继承QuartzJobBean

定义工作明细与触发器,并绑定对应关系

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_22_task</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_22_task</name>
    <description>springboot_22_task</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

QuartzConfig.class

package com.example.springboot_22_task.config;

import com.example.springboot_22_task.quartz.MyQuartz;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QuartzConfig {
    @Bean
    public JobDetail printJobDetail() {
        return JobBuilder.newJob(MyQuartz.class).storeDurably().build();
    }

    @Bean
    public Trigger printJobTrigger() {
        ScheduleBuilder schedBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
        return TriggerBuilder.newTrigger().forJob(printJobDetail()).withSchedule(schedBuilder).build();
    }
}

MyQuartz.class

package com.example.springboot_22_task.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class MyQuartz extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("quartz task run...");
    }
}

6.springboot整合task

开启定时任务功能

设置定时执行的任务,并设定执行周期

定时任务相关配置

MyBean.class

package com.example.springboot_22_task.quartz;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyBean {
    @Scheduled(cron = "0/1 * * * * ?")
    public void print() {
        System.out.println(Thread.currentThread().getName() + " :spring task run...");
    }
}

Springboot22TaskApplication.class

package com.example.springboot_22_task;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class Springboot22TaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot22TaskApplication.class, args);
    }

}

application.yml

spring:
  task:
    scheduling:
      thread-name-prefix: spring_tasks_

7.发送简单邮件

  • SMTP (Simple Mail Transfer Protocol):简单邮件传输协议,用于发送电子邮件的传输协议
  • POP3 ( Post Office Protocol - Version 3):用于接收电子邮件的标准协议
  • IMAP ( Internet Mail Access Protocol) :互联网消息协议,是POP3的替代协议

导入SpringBoot整合JavaMail的坐标

配置JavaMail

 

代码示例:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_23_mail</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_23_mail</name>
    <description>springboot_23_mail</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 SendMailService.interface

package com.example.springboot_23_mail.service;

public interface SendMailService {
    void sendMail();
}

SendMailServiceImpl.class

package com.example.springboot_23_mail.service.impl;

import com.example.springboot_23_mail.service.SendMailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
public class SendMailServiceImpl implements SendMailService {

    @Autowired
    private JavaMailSender javaMailSender;

    private String from = "348904@qq.com";

    private String to = "ter@126.com";

    private String subject = "测试邮件";

    private String context = "测试邮件正文内容";

    @Override
    public void sendMail() {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from + "(小甜甜)");
        message.setTo(to);
        message.setSubject(subject);
        message.setText(context);
        javaMailSender.send(message);
    }
}

Springboot23MailApplicationTests.class

package com.example.springboot_23_mail;

import com.example.springboot_23_mail.service.SendMailService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
class Springboot23MailApplicationTests {


    @Autowired
    private SendMailService sendMailService;

    @Test
    void contextLoads() {
        sendMailService.sendMail();
    }

}

 application.yml

spring:
  mail:
    username: 3864@qq.com
    password: pn............qcjbc
    host: smtp.qq.com

8.发送多部件邮件

附件与HTML文本支持

SendMailServiceImpl2.class

package com.example.springboot_23_mail.service.impl;

import com.example.springboot_23_mail.service.SendMailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;

//@Service
public class SendMailServiceImpl2 implements SendMailService {

    @Autowired
    private JavaMailSender javaMailSender;

    private String from = "344@qq.com";

    private String to = "tar@126.com";

    private String subject = "测试邮件";

    private String context = "<a href='https://www.baidu.com'>点开有惊喜</a>";

    @Override
    public void sendMail() {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from + "(小甜甜)");
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(context, true);

            File f1 = new File("D:\\hdc\\test.txt");
            File f2 = new File("D:\\hdc\\test2.txt");
            helper.addAttachment(f1.getName(), f1);
            helper.addAttachment(f2.getName(), f2);

            javaMailSender.send(message);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

SendMailServiceImpl3.class

package com.example.springboot_23_mail.service.impl;

import com.example.springboot_23_mail.service.SendMailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;

@Service
public class SendMailServiceImpl3 implements SendMailService {

    @Autowired
    private JavaMailSender javaMailSender;

    private String to = "34@qq.com";

    private String from = "ter@126.com";

    private String subject = "测试邮件";

    private String context = "<a href='https://www.baidu.com'>点开有惊喜</a>";

    @Override
    public void sendMail() {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from + "(小甜甜)");
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(context, true);

            File f1 = new File("D:\\hdc\\test.txt");
            File f2 = new File("D:\\hdc\\test2.txt");
            helper.addAttachment(f1.getName(), f1);
            helper.addAttachment(f2.getName(), f2);

            javaMailSender.send(message);
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

application.yml

#spring:
#  mail:
#    username: 34864@qq.com
#    password: pndkzucx
#    host: smtp.qq.com

spring:
  mail:
    username: ter@126.com
    password: HESHJP
    host: smtp.126.com

9.消息简介

企业级应用中广泛使用的三种异步消息传递技术

  • JMS
  • AMQP
  • MQTT

JMS (Java Message Service):一个规范,等同于JDBC规范,提供了与消息服务相关的API接口JMS消息模型

  • peer-2-peer:点对点模型,消息发送到一个队列中,队列保存消息。队列的消息只能被一个消费者消费,或超时
  • publish-subscribe: 发布订阅模型,消息可以被多个消费者消费,生产者和消费者完全独立,不需要感知对方的存在

JMS消息种类

  • TextMessage
  • MapMessage
  • BytesMessage
  • StreamMessage
  • ObjectMessage.
  • Message(只有消息头和属性) 

JMS实现:ActiveMQ、Redis、HornetMQ、RabbitMQ、RocketMQ(没有完全遵守JMS规范)

AMQP 

  • AMQP(advanced message queuing protocol):一种协议(高级消息队列协议,也是消息代理规范),规范了网络交换的数据格式,兼容JMS
  • 优点:具有跨平台性,服务器供应商,生产者,消费者可以使用不同的语言来实现
  • AMQP消息模型
    • direct exchange
    • fanout exchange
    • topic exchange
    • headers exchange
    • system exchange
  • AMQP消息种类: byte[]
  • AMQP实现:RabbitMQ.StormMQ..RocketMQ 

MQTT

MQTT(Message Queueing Telemetry Transport))消息队列遥测传输,专为小设备设计,是物联网(IOT)生态系统中主要成分之一.

Kafka

  • Kafka,一种高吞吐量的分布式发布订阅消息系统,提供实时消息功能。

消息

  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • Kafka

10.购物订单案例-发送短信

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_24_mq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_24_mq</name>
    <description>springboot_24_mq</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

MessageController.class

package com.example.springboot_24_mq.controller;

import com.example.springboot_24_mq.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/msgs")
public class MessageController {
    @Autowired
    private MessageService messageService;

    @GetMapping
    public String doMessage() {
        String id = messageService.doMessage();
        return id;
    }
}

OrderController.class

package com.example.springboot_24_mq.controller;

import com.example.springboot_24_mq.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/orders")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @PostMapping("{id}")
    public void order(@PathVariable String id) {
        orderService.order(id);
    }
}

MessageServiceImpl.class

package com.example.springboot_24_mq.service.impl;

import com.example.springboot_24_mq.service.MessageService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

@Service
public class MessageServiceImpl implements MessageService {
    private ArrayList<String> msgList = new ArrayList<>();

    @Override
    public void sendMessage(String id) {
        System.out.println("待发送短信的订单已纳入待处理队列,id:" + id);
        msgList.add(id);
    }

    @Override
    public String doMessage() {
        String id = msgList.remove(0);
        System.out.println("已完成短信发送业务,id:" + id);
        return id;
    }
}

OrderServiceImpl.class

package com.example.springboot_24_mq.service.impl;

import com.example.springboot_24_mq.service.MessageService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

@Service
public class MessageServiceImpl implements MessageService {
    private ArrayList<String> msgList = new ArrayList<>();

    @Override
    public void sendMessage(String id) {
        System.out.println("待发送短信的订单已纳入待处理队列,id:" + id);
        msgList.add(id);
    }

    @Override
    public String doMessage() {
        String id = msgList.remove(0);
        System.out.println("已完成短信发送业务,id:" + id);
        return id;
    }
}

MessageService.interface

package com.example.springboot_24_mq.service;

public interface MessageService {
    void sendMessage(String id);

    String doMessage();

}

OrderService.interface

package com.example.springboot_24_mq.service;

public interface OrderService {
    void order(String id);

}

application.yml

server:
  port: 8080

11.ActiveMQ安装

  • 下载地址: https://activemq.apache.org/components/classic/download/
  • 安装:解压缩 

启动服务

访问服务器

服务端口:61616,管理后台端口:8161

用户名&密码:admin

12.springboot整合ActiveMQ

导入SpringBoot整合ActiveMQ坐标

配置ActiveMQ(采用默认配置) 

生产与消费消息(使用默认消息存储队列)

生产与消费消息(指定消息存储队列)

使用消息监听器对消息队列监听

流程性业务消息消费完转入下一个消息队列

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_24_mq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_24_mq</name>
    <description>springboot_24_mq</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 application.yml

server:
  port: 8080


spring:
  activemq:
    broker-url: tcp://localhost:61616
  jms:
    template:
      default-destination: itheima

MessageListener.class

package com.example.springboot_24_mq.service.impl.activemq.listener;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;

@Component
public class MessageListener {
    @JmsListener(destination = "order.queue.id")
    @SendTo("order.other.queue.id")
    public String receive(String id) {
        System.out.println("已完成短信发送业务,id:" + id);
        return "new:" + id;
    }
}

MessageServiceActivemqImpl.class

package com.example.springboot_24_mq.service.impl.activemq;

import com.example.springboot_24_mq.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

@Service
public class MessageServiceActivemqImpl implements MessageService {
    @Autowired
    private JmsMessagingTemplate messagingTemplate;

    @Override
    public void sendMessage(String id) {
        System.out.println("待发送短信的订单已纳入待处理队列,id:" + id);
        messagingTemplate.convertAndSend("order.queue.id", id);
    }

    @Override
    public String doMessage() {
        String id = messagingTemplate.receiveAndConvert("order.queue.id", String.class);
        System.out.println("已完成短信发送业务,id:" + id);
        return id;
    }
}

13.RabbitMQ安装

  • RabbitMQ基于Erlang语言编写,需要安装Erlang
  • Erlang
  • 下载地址: https://www.erlang.org/downloads
  • 安装:一键傻瓜式安装,安装完毕需要重启,需要依赖Windows组件
  • 环境变量配置
    • ERLANG_HOME
    • PATH
  • 下载地址: https://rabbitmq.com/install-windows.html
  • 安装:一键傻瓜式安装

RabbitMQ

启动服务

关闭服务

查看服务状态

服务管理可视化(插件形式)

查看已安装的插件列表 

开启服务管理插件

访问服务器

服务端口:5672,管理后台端口:15672

用户名&密码:guest 

14.springboot整合RabbitMQ(direct模式)

配置RabbitMQ(采用默认配置)

定义消息队列(direct)

生产与消费消息(direct)

使用消息监听器对消息队列监听(direct)

使用多消息监听器对消息队列监听进行消息轮循处理(direct)

15. springboot整合RabbitMQ(topic模式)

定义消息队列(topic)

绑定键匹配规则

  • *(星号):用来表示—个单词,且该单词是必须出现的
  • #(井号):用来表示任意数量 

生产与消费消息(topic)

使用消息监听器对消息队列监听(topic)

16.RocketMQ安装

  • 下载地址: https://rocketmq.apache.org/
  • 安装:解压缩
    • 默认服务端口:9876
  • 环境变量配置
    • ROCKETMQ_HOME
    • PATH
    • NAMESRV_ADDR (建议) : 127.0.0.1:9876

命名服务器与broker

 

 

启动命名服务器

启动broker

服务器功能测试:生产者

服务器功能测试:消费者

17.springboot整合RockeMQ

 导入SpringBoot整合RocketMQ坐标

配置RocketMQ(采用默认配置) 

生产消息

 

生产异步消息

使用消息监听器对消息队列监听

 

18.Kafka安装

  • 下载地址: https://kafka.apache.org/downloads
  • windows系统下3.0.0版本存在BUG,建议使用2.X版本
  • 安装:解压缩 

启动zookeeper

默认端口:2181

启动kafka

默认端口:9092

创建topic

查看topic

册除topic

生产者功能测试

消费者功能测试

 

19.springboot整合Kafka 

导入SpringBoot整合Kafka坐标

配置Kafka(采用默认配置) 

生产消息

使用消息监听器对消息队列监听

 

20.监控的意义

  • 监控服务状态是否宕机
  • 监控服务运行指标(内存、虚拟机、线程、请求等)
  • 监控日志
  • 管理服务(服务下线)

监控的实施方式

  • 显示监控信息的服务器:用于获取服务信息,并显示对应的信息
  • 运行的服务:启动时主动上报,告知监控服务器自己需要受到监控 

 

21.SpringBootAdmin

可视化监控平台

  • Spring Boot Admin,开源社区项目,用于管理和监控SpringBoot应用程序。客户端注册到服务端后,通过HTTP请求方式,服务端定期从客户端获取对应的信息,并通过UIl界面展示对应信息。
  • Admin服务端 

 

Admin客户端

 

Admin服务端

 

Admin客户端

Admin服务端

 

设置启用Spring-Admin

Admin客户端

 

 

 22.actuator

  • Actuator提供了SpringBoot生产就绪功能,通过端点的配置与访问,获取端点信息
  • 端点描述了一组监控信息,SpringBoot提供了多个内置端点,也可以根据需要自定义端点信息
  • 访问当前应用所有端点信息:/actuator
  • 访问端点详细信息:/actuator/端点名称

ID

描述

默认启用

auditevents

暴露当前应用程序的审计事件信息。

beans

显示应用程序中所有 Spring bean 的完整列表。

caches

暴露可用的缓存。

conditions

显示在配置和自动配置类上评估的条件以及它们匹配或不匹配的原因。

configprops

显示所有 @ConfigurationProperties 的校对清单。

env

暴露 Spring ConfigurableEnvironment 中的属性。

flyway

显示已应用的 Flyway 数据库迁移。

health

显示应用程序健康信息

httptrace

显示 HTTP 追踪信息(默认情况下,最后 100 HTTP 请求/响应交换)。

info

显示应用程序信息。

integrationgraph

显示 Spring Integration 图。

 

ID

描述

默认启用

loggers

显示和修改应用程序中日志记录器的配置。

liquibase

显示已应用的 Liquibase 数据库迁移。

metrics

显示当前应用程序的指标度量信息。

mappings

显示所有 @RequestMapping 路径的整理清单。

scheduledtasks

显示应用程序中的调度任务。

sessions

允许从 Spring Session 支持的会话存储中检索和删除用户会话。当使用 Spring Session 的响应式 Web 应用程序支持时不可用。

shutdown

正常关闭应用程序。

threaddump

执行线程 dump

Web程序专用端点

ID

描述

默认启用

heapdump

返回一个 hprof  dump 文件。

jolokia

通过 HTTP 暴露 JMX bean(当 Jolokia classpath 上时,不适用于 WebFlux)。

logfile

返回日志文件的内容(如果已设置 logging.file  logging.path 属性)。支持使用 HTTP Range 头来检索部分日志文件的内容。

prometheus

以可以由 Prometheus 服务器抓取的格式暴露指标。

启用指定端点

启用所有端点

暴露端点功能

  • 端点中包含的信息存在敏感信息,需要对外暴露端点功能时手动设定指定端点信息 

属性

默认

management.endpoints.jmx.exposure.exclude

management.endpoints.jmx.exposure.include

*

management.endpoints.web.exposure.exclude

management.endpoints.web.exposure.include

info, health

 

ID

JMX

Web

auditevents

beans

caches

conditions

configprops

env

flyway

health

heapdump

N/A

httptrace

info

ID

JMX

Web

integrationgraph

jolokia

N/A

logfile

N/A

loggers

liquibase

metrics

mappings

prometheus

N/A

scheduledtasks

sessions

shutdown

threaddump

23.info端点指标控制

为info端点添加自定义指标

24.health端点指标控制

为Health端点添加自定义指标

25.metrics端点指标控制

为Metrics端点添加自定义指标 

26.自定义端点 

自定义端点

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1245762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Navicat 技术指引 | GaussDB服务器对象的创建/设计(编辑)

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持对GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构同步、协同合作、数据迁移等&#xff09;&#xff0c;这…

LangChain 8 模型Model I/O:输入提示、调用模型、解析输出

LangChain系列文章 LangChain 实现给动物取名字&#xff0c;LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄LangChain 4用向量数据库Faiss存储&#xff0c;读取YouTube的视频文本搜索I…

YB4051系列设备是高度集成的 Li-lon 和 Li-Pol 线性充电器,针对便携式应用的小容量电池。

YB4051H 300mA 单电池锂离子电池充电器0.1 mA 终端&#xff0c;45nA 电池漏电流 概述&#xff1a; YB4051系列设备是高度集成的 Li-lon 和 Li-Pol 线性充电器&#xff0c;针对便携式应用的小容量电池。它是一个完整的恒流/恒压线性充电器。不需要外部感应电阻&#xff0c;由于…

Linux常用命令——blkid命令

在线Linux命令查询工具 blkid 查看块设备的文件系统类型、LABEL、UUID等信息 补充说明 在Linux下可以使用blkid命令对查询设备上所采用文件系统类型进行查询。blkid主要用来对系统的块设备&#xff08;包括交换分区&#xff09;所使用的文件系统类型、LABEL、UUID等信息进行…

React基础入门

文章目录 创建项目组件和事件更新状态导出组件jsx react是目前最流行的前端框架&#xff0c;几乎也不同太介绍了。 创建项目 首先下载node.js&#xff0c;安装成功后&#xff0c;最好换成国内的源 npm config set registry https://registry.npm.taobao.org然后就可以使用脚…

NVM得介绍和详细使用教程

NVM​​​​​​​&#xff08;Node Version Manager&#xff09;是一个用于管理多个Node.js版本的工具。它允许您在同一台计算机上轻松地切换和管理不同的Node.js版本。以下是NVM的介绍和详细使用教程&#xff1a; 安装NVM&#xff1a; 首先&#xff0c;您需要在计算机上安装N…

Echarts仪表盘3.0

代码&#xff1a; <html> <head><title>图表绘制</title><style type"text/css">#dashboard {width: 402px;height: 293px;margin: 50px auto;}</style> </head> <body><!-- 为ECharts准备一个具备大小&#xf…

ssm 服务器运维管理的论坛系统-98166(免费领取源码)计算机毕业设计选题开题+程序定制+论文书写+答辩ppt书写 包售后 全流程

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;服务器运维管理的论坛系统当然也不能排除在外。服务器运维管理的论坛系统是以实际运用为开发背景&#xff0c;运用软件工…

c语言-数组长度的计算(结构体数组,字符串数组)

数组的长度我们可以直接根据函数声明得到数组的长度&#xff0c;或者可以通过计算的方法如下&#xff1a; 数组长度sizeof(数组名)/sizeof(数组类型) 测试代码如下&#xff1a;测试int整形数组&#xff0c;char字符数组&#xff0c;字符串数组&#xff0c;结构体数组。 #includ…

办公技巧:Word中插入图片、形状、文本框排版技巧

目录 一、插入图片排版技巧 二、添加形状排版技巧 三、插入“文本框”排版技巧 我们平常在制作word时候经常会遇到插入选项卡下的图片、形状和文本框这三种情况下&#xff0c;那么如何使得Word文档当中添加这三个元素的同时&#xff0c;又能保证样式美观呢&#xff0c;今天小…

Nginx环境搭建:安装与卸载

目录 一、卸载 二、安装 注&#xff1a;如果直接使用yum安装nginx&#xff0c;则默认安装路径为&#xff1a;/usr/share/nginx/ 下面这种方式我们是指定了安装目录 一、卸载 因为我之前的虚拟机上面已经有了nginx服务&#xff0c;所以这里可以先介绍一下nginx的卸载方法&a…

vulnhub4

靶机地址: https://download.vulnhub.com/admx/AdmX_new.7z 信息收集 fscan 扫一下 ┌──(kali㉿kali)-[~/Desktop/Tools/fscan] └─$ ./fscan_amd64 -h 192.168.120.138 ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ …

joplin笔记同步 到腾讯云S3

创建存储桶 打开腾讯云的存储桶列表&#xff0c;点击“创建存储桶”&#xff0c;输入名称&#xff0c;选择地域&#xff08;建议选择离自己较近的地域以降低访问时延&#xff09;和访问权限&#xff08;建议选择“私有读写”&#xff09;。 s3 存储桶&#xff1a; 存储桶的名称…

AI 视频 | Stable Video Diffusion 来了!(附体验地址)

1. 介绍 11 月 21 日&#xff0c;Stability AI 推出了 Stable Video Diffusion&#xff0c;这是 Stability AI 的第一个基于图像模型 Stable Diffusion 的生成式视频基础模型。 目前 Stability AI 已经在 GitHub 上开源了 Stable Video Diffusion 的代码&#xff0c;在 Huggin…

geemap学习笔记013:为遥感动态GIF图添加图名

前言 遥感动态GIF图可以展示地理区域随时间的变化&#xff0c;这对于监测自然灾害、湿地变化、城市扩展、农田变化等方面非常有用&#xff0c;并且可以反复观察图像&#xff0c;以更深入地了解地表的动态变化。本节主要是对遥感动态GIF图添加图名&#xff0c;以便于更好地理解…

BUUCTF 刷新过的图片 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 浏览图片的时候刷新键有没有用呢 注意&#xff1a;得到的 flag 请包上 flag{} 提交 密文&#xff1a; 下载附件&#xff0c;解压得到一个.jpg图片。 解题思路&#xff1a; 1、根据题目提示&#xff0c;结合键盘上…

Go语言网络爬虫工程经验分享:pholcus库演示抓取头条新闻的实例

网络爬虫是一种自动从互联网上获取数据的程序&#xff0c;它可以用于各种目的&#xff0c;如数据分析、信息检索、竞争情报等。网络爬虫的实现方式有很多&#xff0c;不同的编程语言和框架都有各自的优势和特点。在本文中&#xff0c;我将介绍一种使用Go语言和pholcus库的网络爬…

qgis添加postgis数据

左侧浏览器-PostGIS-右键-新建连接 展开-双击即可呈现 可以点击编辑按钮对矢量数据编辑后是直接入库的&#xff0c;因此谨慎使用。

【JavaWeb】HTMLCSSJavaScript

HTML&CSS&JavaScript 文章目录 HTML&CSS&JavaScript一、开发工具及在线帮助文档二、 HTML2.1 HTML&CSS&JavaScript的作用2.2 HTML基础结构2.3 HTML概念词汇解释2.4 HTML的语法规则2.5 常用标签 三、CSS3.1 引入方式3.2 CSS选择器3.3 CSS浮动3.4 CSS定位…