springboot整合邮箱功能二(实战)

news2024/11/14 1:26:26

【SpringBoot整合Email发送邮件】_ζั͡ ั͡空 ั͡ ั͡白�的博客-CSDN博客

https://www.cnblogs.com/erlou96/p/16878192.html#_label1_5 

1. 准备工作

1.1 qq邮箱设置

  • 本文默认使用qq邮箱来发送邮件,然后使用一个在线临时邮箱来接收邮件。
  • 为了让程序能够通过qq邮箱来发送邮件,必须在qq邮箱中配置一下打开IMAP/SMTP服务

在这里插入图片描述

开启的时候,需要通过手机发送一条信息作为验证,验证成功后,会给你一个授权码,这个后面我们要用到

在这里插入图片描述

在这里插入图片描述

2. SpringBoot项目配置

2.1 springboot项目中引入email依赖

<?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 http://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.11</version>-->
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <project-name>spring-boot-email</project-name>

        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <groupId>org.example</groupId>
    <artifactId>${project-name}</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>${project-name}</name>
    <description>${project-name}</description>

    <dependencies>
        <!--发送邮件的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

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

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

        <!-- ================= 应用 ================== -->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.25</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.1-android</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.1</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.2 application.yml配置信息

server:
  port: 8000
  max-http-header-size: 8192
  servlet:
    encoding:
      charset: UTF-8
      force: true
      enabled: true

#配置日志
logging:
  level:
    root: info
spring:
  application:
    name: spring-boot-email
  mvc.async.request-timeout: 20000

  mail:
    #    host: "smtp.163.com" # 发件服务器地址
    #    port: 25 # 常用邮件端口25、109、110、143、465、995、993、994 如果开启了SSL安全则使用对应的端口号,25为非加密端口号
    #    username: admin@163.com # 发送邮件的账号
    #    password: 123456 # 配置密码,注意,不是真正的密码,而是刚刚申请到的授权码
    #    default-encoding: utf-8 # 设置编码
    host: smtp.exmail.qq.com
    port: 465
    username: test@xxx.cn
    password: 123123
    default-encoding: utf-8 # 设置编码
    protocol: smtp
    properties: # 设置邮件超时时间防止服务器阻塞
      timeout: 5000
      connection-timeout: 5000
      write-timeout: 5000
      mail:
        debug: true # 表示开启 DEBUG 模式,这样,邮件发送过程的日志会在控制台打印出来,方便排查错误
        # 官方建议使用 465 端口,而 465 端口是 SSL 协议的,所以不仅要换端口,
        # 还需要进行 SSL 协议替换。下面是在 application.properties 进行的邮件发送相关配置,
        smtp:
          socketFactory:
            port: 465
          #socketFactoryClass: javax.net.ssl.SSLSocketFactory #配饰 SSL 加密工厂
          ssl:
            enable: true
  thymeleaf:
    cache: false
    mode: LEGACYHTML5 # 类型
    prefix: classpath:/templates/ # 模板存放的位置
    suffix: .html # 模板的后缀

2.3  创建EmailModel

用于封装邮件中需要包含的信息

package org.example.entity;

import java.io.Serializable;
import java.util.Map;

/**
 * @author test 2023-05-08 10:52:59
 */
public class EmailModel implements Serializable {
    /**
     * 收件人邮箱
     */
    private String[] recipientMailbox;

    /**
     * 邮件正文内容
     */
    private String content;

    /**
     * 邮件主题
     */
    private String title;

    /**
     * 抄送人邮箱
     */
    private String[] ccMailbox;

    /**
     * 加密抄送人邮箱
     */
    private String[] bccMailbox;

    /**
     * 真实名称/附件路径
     * enclosures: {“fileNmae”: "filePath+fileNmae"}
     */
    private Map<String, String> enclosures;

    //    附件是否添加的到正文,默认false不添加
    //    private Boolean is_;


    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String[] getRecipientMailbox() {
        return recipientMailbox;
    }

    public void setRecipientMailbox(String[] recipientMailbox) {
        this.recipientMailbox = recipientMailbox;
    }

    public String[] getCcMailbox() {
        return ccMailbox;
    }

    public void setCcMailbox(String[] ccMailbox) {
        this.ccMailbox = ccMailbox;
    }

    public String[] getBccMailbox() {
        return bccMailbox;
    }

    public void setBccMailbox(String[] bccMailbox) {
        this.bccMailbox = bccMailbox;
    }

    public Map<String, String> getEnclosures() {
        return enclosures;
    }

    public void setEnclosures(Map<String, String> enclosures) {
        this.enclosures = enclosures;
    }
}

2.4 创建EmailService

package org.example.service;

import org.example.entity.EmailModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Date;
import java.util.Map;

/**
 * @author Administrator
 */
@Service
@EnableAsync
public class EmailService {
    Logger log = LoggerFactory.getLogger(getClass());

    /**
     * 将配置文件中的username注入到MAIL_USERNAME中, 这是发送人的邮箱地址
     */
    @Value("${spring.mail.username}")
    public String MAIL_USERNAME;

    /**
     * JavaMailSender类的对象, 是springboot自动装配的
     */
    @Resource
    private JavaMailSender javaMailSender;

    public void sendModleMail(EmailModel model) throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setSubject(model.getTitle()); // 邮件标题
        helper.setFrom(MAIL_USERNAME); // 发送者邮箱
        helper.setTo(model.getRecipientMailbox()); // 收件人邮箱
        if (model.getCcMailbox() != null && model.getCcMailbox().length != 0) {
            helper.setCc(model.getCcMailbox()); // 抄送人
        }
        if (model.getBccMailbox() != null && model.getBccMailbox().length != 0) {
            helper.setBcc(model.getBccMailbox()); // 加密抄送
        }
        helper.setSentDate(new Date()); // 发送日期
        helper.setText(model.getContent()); // 发送内容
        if (!model.getEnclosures().isEmpty()) {
            log.info("-------[Iterator循环遍历]通过keySet取出map数据---------");
            for (String key : model.getEnclosures().keySet()) {
                helper.addAttachment(key, new File(model.getEnclosures().get(key)));// 预览文件
                // System.out.println("key值:"+key+" value值:"+model.getEnclosures().get(key));
            }

        }
        // helper.addAttachment("2.jpg", new File("E:\\pic\\2.jpg"));//预览文件
        //        helper.addInline("p01",new FileSystemResource(new File("E:\\pic\\2.jpg")));//配合前端可以直接预览图片
        //        helper.addInline("p02",new FileSystemResource(new File("E:\\pic\\2.jpg")));
        javaMailSender.send(mimeMessage);
    }

    /**
     * 发送简单的邮件(内容为纯文本邮件)
     * @param model
     * @return
     */
    public boolean sendSimpleEmail(EmailModel model) {
        // 发一个简单邮件,
        // 使用SimpleMessage对象, 调用setText方法, 里面的字符串是带有html标签的字符串, 在发送邮件的时候会自动解析正文中的html标签
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();

        // 设置发件人账号
        simpleMailMessage.setFrom(MAIL_USERNAME);

        // 设置接收人账号
        simpleMailMessage.setTo(model.getRecipientMailbox());

        // 设置邮件标题
        simpleMailMessage.setSubject(model.getTitle());

        // 设置邮件正文内容
        simpleMailMessage.setText(model.getContent());

        // 发送邮件
        javaMailSender.send(simpleMailMessage);
        log.info("send simple email success!");
        return true;
    }

    /**
     * 使用MimeMessage来作为对象发送,
     * 但是邮件内容需要通过 MimeMessageHelper 对象来进行封装进MimeMessage 里
     * 注意:
     * 如果发送的内容包括html标签, 则需要 helper.setText(email.getContent(),true);
     * 第二个参数要为true,表示开启识别html标签.默认是false,也就是不识别.
     * @param model
     * @return
     */
    public boolean sendMimeEmail(EmailModel model) {
        // 发一个复杂一点的邮件
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);

        try {
            // 设置发件人账号
            helper.setFrom(MAIL_USERNAME);

            // 设置接收人账号
            helper.setTo(model.getRecipientMailbox());

            // 设置邮件标题
            helper.setSubject(model.getTitle());

            // 设置邮件正文内容 ,第二个参数开启html识别
            helper.setText(model.getContent(), true);

            // 发送邮件
            javaMailSender.send(mimeMessage);
            log.info("send mime email success!");
            return true;
        } catch (MessagingException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 使用 MimeMessage 发送复杂邮件
     * @param model
     * @return
     */
    public boolean sendAttachMimeEmail(EmailModel model) {
        // 发一个复杂一点的邮件
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();

        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

            // 设置发件人账号
            helper.setFrom(MAIL_USERNAME + "(昵称123)");

            // 设置接收人账号
            helper.setTo(model.getRecipientMailbox());

            // 设置邮件标题
            helper.setSubject(model.getTitle());

            // 设置邮件正文内容 ,第二个参数开启html识别
            helper.setText(model.getContent(), true);

            Map<String, String> enclosures = model.getEnclosures();

            // 创建要传递的附件对象
            // import org.springframework.util.CollectionUtils;
            if (!CollectionUtils.isEmpty(enclosures)) {
                for (String key : enclosures.keySet()) {
                    // File file = new File(“D:\mybatis.doc”);
                    File file = new File(enclosures.get(key));
                    // 通过MimeMessageHelper对象的addAttachment方法来传递附件, 第一个参数为附件名, 第二个参数为FIle对象
                    helper.addAttachment(key, file);
                }
            }

            // 发送邮件
            javaMailSender.send(mimeMessage);
            log.info("send mime email success!");
            return true;
        } catch (MessagingException e) {
            e.printStackTrace();
            return false;
        }
    }
}

2.5 创建EmailController 

package org.example.controller;

import org.example.entity.EmailModel;
import org.example.service.EmailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.MessagingException;

/**
 * @description:
 */
@RestController
public class EmailController {
    Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    EmailService emailService;

    @RequestMapping("test")
    public String test() {
        log.info("ok");
        return "ok";
    }

    /**
     * {
     *     "title": "测试主题",
     *     "content": "测试邮件测试人test",
     *     "recipientMailbox": [
     *         "2222222@qq.com",
     *         "test@xxx.cn"
     *     ],
     *     "ccMailbox": ["test@163.com"],
     *     "bccMailbox": [],
     *     "enclosures": {
     *         "dog2.jpg": "E:\\img\\dog2.png"
     *     }
     * }
     * @param model
     * @return
     * @throws MessagingException
     */
    @PostMapping("sendModleMail")
    public String sendModleMail(@RequestBody EmailModel model) throws MessagingException {
        emailService.sendModleMail(model);
        return "success!";
    }

    /**
     * {
     *     "recipientMailbox": [
     *         "test@xxx.cn"
     *     ],
     *     "title": "简单测试主题",
     *     "content": "测试邮件测试人test"
     * }
     * @param model
     * @return
     * @throws MessagingException
     */
    @RequestMapping("sendSimpleEmail")
    public String sendSimpleEmail(@RequestBody EmailModel model) {
        emailService.sendSimpleEmail(model);
        return "success!";
    }

    /**
     * {
     *     "recipientMailbox": [
     *         "test@xxx.cn"
     *     ],
     *     "title": "html测试主题",
     *     "content": "<h1>测试邮件测试人test</h1>
     *        <a href=\"https://www.baidu.com/\">点击跳转百度</a>
     *        <img src=\"https://img-blog.csdnimg.cn/2092623a09ed4d19ac4b9ab5301462cf.png\"></img>"
     * }
     * @param model
     * @return
     * @throws MessagingException
     */
    @RequestMapping("sendMimeEmail")
    public String sendMimeEmail(@RequestBody EmailModel model) {
        emailService.sendMimeEmail(model);
        return "success!";
    }

    /**
     * {
     *     "recipientMailbox": [
     *         "test@xxx.cn"
     *     ],
     *     "title": "附件测试主题",
     *     "content": "<img src=\"https://img-blog.csdnimg.cn/2092623a09ed4d19ac4b9ab5301462cf.png\"></img>",
     *     "enclosures": {
     *         "dog2.jpg": "E:\\img\\dog2.png"
     *     }
     * }
     * @param model
     * @return
     */
    @RequestMapping("sendAttachMimeEmail")
    public String sendAttachMimeEmail(@RequestBody EmailModel model) {
        emailService.sendAttachMimeEmail(model);
        return "success!";
    }
}

3. 邮件发送类型讲解

下文中所有的实现都是写在 EmailService 类中。

3.1 发送简单的邮件(内容为纯文本邮件)

通过SimpleMailMessage对象来发送简单邮件,邮件的内容只能是纯文本,将内容封装到该对象中,再通过javaMailSender对象来发送邮件

/**
 * 发送简单的邮件(内容为纯文本邮件)
 * @param model
 * @return
 */
public boolean sendSimpleEmail(EmailModel model) {
	// 发一个简单邮件,
	// 使用SimpleMessage对象, 调用setText方法, 里面的字符串是带有html标签的字符串, 在发送邮件的时候会自动解析正文中的html标签
	SimpleMailMessage simpleMailMessage = new SimpleMailMessage();

	// 设置发件人账号
	simpleMailMessage.setFrom(MAIL_USERNAME);

	// 设置接收人账号
	simpleMailMessage.setTo(model.getRecipientMailbox());

	// 设置邮件标题
	simpleMailMessage.setSubject(model.getTitle());

	// 设置邮件正文内容
	simpleMailMessage.setText(model.getContent());

	// 发送邮件
	javaMailSender.send(simpleMailMessage);
	log.info("send simple email success!");
	return true;
}

postman脚本 

{
    "recipientMailbox": [
        "test@xxxx.cn"
    ],
    "title": "简单测试主题",
    "content": "<h1>测试邮件测试人test</h1>"
}

发送请求,将email对象中的数据初始化

在这里插入图片描述

查看是否收到邮件,内容和我们发送的一样

在这里插入图片描述

3.2 发送简单的邮件(内容可以识别html标签)

3.2.1 方法1

  • 直接和上面一样,使用SimpleMessage对象,调用setText方法,里面的字符串是带有html标签的字符串,在发送邮件的时候会自动解析正文中的html标签
  • 代码和上面一样,只需要修改发送email的内容即可

在这里插入图片描述

在这里插入图片描述

3.2.2 方法2

使用MimeMessage来作为对象发送,但是邮件内容需要通过MimeMessageHelper对象来进行封装进MimeMessage里

注意:

如果发送的内容包括html标签,则需要 helper.setText(email.getContent(),true);第二个参数要为true,表示开启识别html标签.默认是false,也就是不识别.

在这里插入图片描述

/**
 * 使用MimeMessage来作为对象发送,
 * 但是邮件内容需要通过 MimeMessageHelper 对象来进行封装进MimeMessage 里
 * 注意:
 * 如果发送的内容包括html标签, 则需要 helper.setText(email.getContent(),true);
 * 第二个参数要为true,表示开启识别html标签.默认是false,也就是不识别.
 * @param model
 * @return
 */
public boolean sendMimeEmail(EmailModel model) {
	// 发一个复杂一点的邮件
	MimeMessage mimeMessage = javaMailSender.createMimeMessage();
	MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);

	try {
		// 设置发件人账号
		helper.setFrom(MAIL_USERNAME);

		// 设置接收人账号
		helper.setTo(model.getRecipientMailbox());

		// 设置邮件标题
		helper.setSubject(model.getTitle());

		// 设置邮件正文内容 ,第二个参数开启html识别
		helper.setText(model.getContent(), true);

		// 发送邮件
		javaMailSender.send(mimeMessage);
		log.info("send mime email success!");
		return true;
	} catch (MessagingException e) {
		e.printStackTrace();
		return false;
	}
}

postman脚本

{
    "recipientMailbox": [
        "test@xxxx.cn"
    ],
    "title": "链接地址测试主题",
    "content": "<a href=\"https://www.baidu.com/\">点击跳转百度</a>"
}

在这里插入图片描述

在这里插入图片描述

3.3 发送带静态资源(图片)的邮件中

方法和上面方法2中的代码是一致的,只相当于邮件内容还是html标签,现在就是使用的<img>标签

在这里插入图片描述

postman脚本 

{
    "recipientMailbox": [
        "test@xxxx.cn"
    ],
    "title": "图片测试主题",
    "content": "<img src=\"https://img-blog.csdnimg.cn/2092623a09ed4d19ac4b9ab5301462cf.png\"></img>"
}

效果图:

在这里插入图片描述

3.5 发送带附件的邮件

  • 我们的邮件中可能还需要附带一些附件,比如文件,或者jar包等等,如何发送附件呢?
  • 也是使用MimeMessage对象和MimeMessageHelper对象,但是在创建MimeMessageHelper对象的时候需要加一个参数为true.

在这里插入图片描述

/**
 * 使用 MimeMessage 发送复杂邮件
 * @param model
 * @return
 */
public boolean sendAttachMimeEmail(EmailModel model) {
	// 发一个复杂一点的邮件
	MimeMessage mimeMessage = javaMailSender.createMimeMessage();

	try {
		MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

		// 设置发件人账号
		helper.setFrom(MAIL_USERNAME + "(昵称123)");

		// 设置接收人账号
		helper.setTo(model.getRecipientMailbox());

		// 设置邮件标题
		helper.setSubject(model.getTitle());

		// 设置邮件正文内容 ,第二个参数开启html识别
		helper.setText(model.getContent(), true);

		Map<String, String> enclosures = model.getEnclosures();

		// 创建要传递的附件对象
		// import org.springframework.util.CollectionUtils;
		if (!CollectionUtils.isEmpty(enclosures)) {
			for (String key : enclosures.keySet()) {
				// File file = new File(“D:\mybatis.doc”);
				File file = new File(enclosures.get(key));
				// 通过MimeMessageHelper对象的addAttachment方法来传递附件, 第一个参数为附件名, 第二个参数为FIle对象
				helper.addAttachment(key, file);
			}
		}

		// 发送邮件
		javaMailSender.send(mimeMessage);
		log.info("send mime email success!");
		return true;
	} catch (MessagingException e) {
		e.printStackTrace();
		return false;
	}
}

postman脚本 

{
    "recipientMailbox": [
        "test@xxx.cn"
    ],
    "title": "附件测试主题",
    "content": "<img src=\"https://img-blog.csdnimg.cn/2092623a09ed4d19ac4b9ab5301462cf.png\"></img>",
    "enclosures": {
        "dog2.jpg": "E:\\2.新员工\\img\\dog2.png"
    }
}

重点:

  1. 第二个参数为true 
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
File file = new File(“D:\Users\Administrator\Desktop\picture\mybatis.doc”);
  1. /调用helper的addAttachment来添加附件
helper.addAttachment(file.getName(),file);

在这里插入图片描述

附件上传成功!
在这里插入图片描述

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

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

相关文章

Semantic Segmentation using Adversarial Networks代码

代码来源 首先看一下模型架构&#xff1a; 损失计算&#xff1a; class GANUpdater(chainer.training.StandardUpdater, UpdaterMixin):def __init__(self, *args, **kwargs):self.model kwargs.pop(model) # set for exeptions.Evaluatorself.gen, self.dis self.model[g…

O2OA中如何使用PostgreSQL + Citus 实现分布式数据库实现方案?

虽然 O2OA 数据表高效的表结构以及索引的设计已经极大程度地保障了数据存取操作的性能&#xff0c;但是随着使用时间从增长&#xff0c;数据表存放的数据量也会急剧增长。此时&#xff0c;仍然需要有合适的方案来解决数据量产生的系统性能瓶颈。本文介绍通过 PostgreSQL Citus…

2023年5月DAMA-CDGA/CDGP数据治理认证开班啦,我要报名学习

6月18日DAMA-CDGA/CDGP数据治理认证考试开放报名中&#xff01; 考试开放地区&#xff1a;北京、上海、广州、深圳、长沙、呼和浩特、杭州、南京、济南、成都、西安。其他地区凑人数中… DAMA-CDGA/CDGP数据治理认证班进行中&#xff0c;报名从速&#xff01; DAMA认证为数据…

【刷题之路】LeetCode 234. 回文链表

【刷题之路】LeetCode 234. 回文链表 一、题目描述二、解题1、方法1——复制值到数组后用双指针1.1、思路分析1.2、代码实现 2、方法2——反转另一半链表2.1、思路分析2.2、代码实现2.3、补充 3、方法3——递归3.1、思路分析3.2、代码实现 一、题目描述 原题连接&#xff1a; …

计算机图形学 | 裁剪与屏幕映射

计算机图形学 | 裁剪与屏幕映射 计算机图形学 | 裁剪与屏幕映射8.1 裁剪思想裁剪的概念编码裁剪法中点裁剪法Liang-Barsky算法 8.2 真正的裁剪——在三维空间遇见多边形真正的裁剪多边形的裁剪Weiler-Atherton算法三维空间中的裁剪 8.3 几何阶段的完结&#xff1a;屏幕映射屏幕…

API 接口的使用和功能

随着互联网的快速发展&#xff0c;API接口已经成为了现代开发中不可或缺的一部分。API接口可以让你的应用程序与其他应用程序、系统或服务进行数据交流和集成。如果你正在开发应用程序&#xff0c;那么最好的方法就是使用API接口来增强功能和性能。 我们的API接口是为您的应用…

上财黄烨:金融科技人才的吸引与培养

“金融科技企业在吸引人才前&#xff0c;应先完善人才培养机制&#xff0c;建立员工画像&#xff0c;有针对性地培训提高成员综合素质。” ——上海金融智能工程技术研究中心上海财经大学金融科技研究院秘书长&院长助理黄烨老师 01.何为数字人才&#xff1f; 目前大多数研…

什么,你不会Windows本地账户和本地组账户的管理加固?没意思

什么&#xff0c;你不会Windows本地账户和本地组账户的管理加固&#xff1f;没意思 1.图形化界面方式管理用户2.图形化界面方式管理用户组3.命令行界面方式管理用户4.命令行界面方式管理账户组5.账户安全基线加固账户检查口令检查 1.图形化界面方式管理用户 1、打开管理界面 …

运维自动化工具 Ansible的安装部署和常用模块介绍

ansible安装 ansible的安装有很多种方式 官方文档&#xff1a;https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.ht ml https://docs.ansible.com/ansible/latest/installation_guide/index.html 下载 https://releases.ansible.com/ansible…

Java入门全网最详细 - 从入门到转行

Java基础入门 - 坚持 Java 基本介绍Java 学习须知Java 学习文档Java 基础Java Hello WorldJava 变量Java 数据类型Java 运算符Java 修饰符Java 表达式 & 语句 & 代码块Java 注释--------------------------------------------------------------------------Java 控制语…

在vue中引入高德地图

既然要用到高德地图首先要申请成为高德地图开发者&#xff0c;并申请使用高德地图的key这两点在这篇文章就不过多赘述&#xff0c;有需要的小伙伴可以查查资料&#xff0c;或者去高德地图api官网都有很详细的介绍。高德地图官网 简单提一下申请秘钥流程&#xff08;web端&#…

Python入门教程+项目实战-12.2节: 字典的操作方法

目录 12.2.1 字典的常用操作方法 12.2.2 字典的查找 12.2.3 字典的修改 12.2.4 字典的添加 12.2.5 字典的删除 12.2.6 知识要点 12.2.7 系统学习python 12.2.1 字典的常用操作方法 字典类型是一种抽象数据类型&#xff0c;抽象数据类型定义了数据类型的操作方法&#x…

想成为神经网络大师?这些常用算法和框架必须掌握!

神经网络是机器学习和人工智能领域中的一种常用算法&#xff0c;它在图像识别、自然语言处理等方面都有广泛的应用。如果你想入门神经网络&#xff0c;那么这篇文章就是为你准备的。 首先&#xff0c;了解基本概念是入门神经网络的基础。神经元是神经网络的基本组成部分&#x…

AQS底层源码解析

可重入锁 又叫递归锁&#xff0c;同一个线程在外层方法获得锁的时候&#xff0c;再进入该线程内层方法会自动获取锁&#xff0c;&#xff08;前提锁对象是同一个对象&#xff09;。不会因为之前已经获取过还没释放而阻塞。 Synchronized和ReentrantLock都是可重入锁&#xff…

玩游戏时突然弹出”显示器驱动程序已停止响应并且已恢复”怎么办

随着3A游戏大作不断面市&#xff0c;用户也不断地提升着自己的硬件设备。但是硬件更上了&#xff0c;却还会出现一些突如其来的情况&#xff0c;比如正准备开启某款游戏时&#xff0c;电脑右下角突然出现“显示器驱动程序已停止响应并且已恢复”。遇事不慌&#xff0c;驱动人生…

创新指南|5大策略让创新业务扩张最大避免“增长痛苦”

公司在开发和孵化新业务计划方面进行了大量投资&#xff0c;但很少有公司遵循严格的途径来扩大新业务规模。虽然80%的公司声称构思和孵化新企业&#xff0c;但只有16%的公司成功扩大了规模。典型案例是百思买在许多失败倒闭的扩大新业务取得了成功。它经历了建立新业务所需的3个…

如何使用 Python+selenium 进行 web 自动化测试?

使用Pythonselenium进行web自动化测试主要分为以下步骤&#xff1a; 在华为工作了10年的大佬出的Web自动化测试教程&#xff0c;华为现用技术教程&#xff01;_哔哩哔哩_bilibili在华为工作了10年的大佬出的Web自动化测试教程&#xff0c;华为现用技术教程&#xff01;共计16条…

VMware ESXi 7.0 U3m macOS Unlocker OEM BIOS (标准版和厂商定制版)

VMware ESXi 7.0 U3m macOS Unlocker & OEM BIOS (标准版和厂商定制版) 提供标准版和 Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮)、Cisco (思科) 定制版镜像 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-esxi-7-u3-oem/&#xff0c;查看最新版…

AC/DC、DC/DC转换器

什么是AC&#xff1f; Alternating Current&#xff08;交流&#xff09;的首字母缩写。 AC是大小和极性&#xff08;方向&#xff09;随时间呈周期性变化的电流。 电流极性在1秒内的变化次数被称为频率&#xff0c;以Hz为单位表示。 什么是DC&#xff1f; Direct Current&…

C语言的存储类别,链接和内存管理

目录 1.1作用域 1.2链接 1.3存储期 1.4存储类别 1.4.1自动变量 1.4.2寄存器变量 1.4.3块作用域的静态变量 1.4.4外部链接的静态变量 1.4.5内部链接的静态变量 1.4.6存储类别说明符 1.5动态内存管理 1.5.1出现原因 栈内存 数据段与代码段 堆内存 1.5.2动态内存函…