2021.2.24 update

1 overview

Spring Boot integrates the mail service, including sending plain text messages as well as messages with attachments.

2 Email Address Selection

The QQ mailbox is selected here as the mailbox to send, of course, you can also choose other mailbox, but the specific configuration is different.

To use QQ email, you need to enable SMTP service in your personal Settings:

After sending the SMS message to complete the authentication, there will be an authorization code, first copy and save.

3 Concrete Implementation

3.1 depend on

Provides starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
Copy the code

Gradle:

implementation 'org.springframework.boot:spring-boot-starter-mail'
Copy the code

3.2 Mail Interface

There are only two simple interfaces, one for sending plain text and one for sending attachments:

public interface MailService {
    void sendSimpleMail(String to,String subject,String content);
    void sendAttachmentMail(String to, String subject, String content, Path file) throws MessagingException;
}
Copy the code

3.3 Interface Implementation

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MailServiceImpl implements MailService{
    private final JavaMailSender sender;

    @Value("${spring.mail.username}")
    private String from;

    @Override
    public void sendSimpleMail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);
        sender.send(message);
    }

    @Override
    public void sendAttachmentMail(String to, String subject, String content, Path file) throws MessagingException {
        MimeMessage message = sender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message,true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content);
        helper.addAttachment(file.getFileName().toString(),newFileSystemResource(file)); sender.send(message); }}Copy the code

JavaMailSender is the mail sending interface carried by Spring Boot. After injection, it can send SimpleMailMessage and MimeMessage type information.

  • SimpleMailMessage: a simple message object that encapsulates some common properties, such as mailing address and receiving address, sending date, subject, content, etc
  • MimeMessageSend:MIMEType of email message,MIMERefers to theMultipurpose Internet Mail ExtensiosnsIs an Internet standard for describing message content types that can contain text, images, audio, video, and other application-specific data
  • MimeMessageHelper: used to setMimeMessageProperty of the class, which can be usedaddAttachmentAdd attachments
  • setFrom/setTo/setSubject/setText: Indicates Settings respectivelyMailing address/address/The theme/content

3.4 the test class

@SpringBootTest
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
class DemoApplicationTests {
	private final MailService service;

	@Test
	void contextLoads(a) throws URISyntaxException, MessagingException {
		service.sendSimpleMail("[email protected]"."That's the theme."."This is the content.");
		service.sendAttachmentMail("[email protected]"."That's the theme."."This is the content.", Path.of(Objects.requireNonNull(getClass().getClassLoader().getResource("pic/1.jpg")).toURI()));
		// Attached is PIC /1.jpg under resources
		service.sendAttachmentMail("[email protected]"."That's the theme."."This is the content.", Path.of("/"."srv"."http"."1.jpg"));
		// The attachment is/SRV/HTTP /1.jpg
	}
Copy the code

Send text directly to specify the subject and content, send with attachments:

  • If it isresourcesUnder the content, usegetClass().getClassLoader().getReource("xxx/xxx")
  • If it is an absolute path, usePath.of("/","path1","path2",... ,"filename")

3.5 Configuration File

spring:
  mail:
    host: smtp.qq.com
    username: [email protected]
    password: xxxxxxxxxx
    port: 465
    properties:
      mail:
        smtp:
          ssl:
            enable: true
          auth: true
          starttls:
            enable: true
            required: true
Copy the code

You only need to change the username and password for Demo.

  • username: Indicates the email address of the sender
  • password: Not email password, but authorization code, just openedSMTPAuthorization code for service occurrence

Other configuration instructions:

  • host:SMTPServer address
  • port: Port, optional465/587.hostAs well asportYou can refer toQQemailThe document
  • properties: It’s full of security Settings. Turn it onSSLCertification and so on

3.6 test

Change the mailbox of the test class and run the unit test.

If you fail, check out this list of common error codes and possible solutions.

4 encryption

The user name and password are directly written in the configuration file. Therefore, the configuration file must be encrypted.

For details, see my previous Project The Force article here.

4.1 depend on

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>
Copy the code

Gradle:

implementation("Com. Making. Ulisesbocchio: jasypt - spring - the boot - starter: 3.0.3." ")
Copy the code

4.2 Configuration File

The configuration file only needs to be encrypted password:

jasypt:
  encryptor:
    password: test
Copy the code

By default, PBE encryption algorithm is used. PBE is actually a combination of encryption algorithm. By default, HCMA algorithm (hybrid CMA-ES algorithm) +SHA512 message digest algorithm +AES256 symmetric encryption algorithm is used.

In addition, if you do not want to write an encrypted password directly into the configuration file, you can parameterize the password using the following three methods:

Command line arguments (runtime Settings) :

java -jar xxx.jar --jasypt.encryptor.password=test
Copy the code

Application environment variables (runtime Settings) :

java -Djasypt.encryptor.password=test -jar xxx.jar
Copy the code

System environment variables (set in the configuration file) :

jasypt:
  encryptor:
    password: ${TEST}
# means to get the value of the environment variable TEST as the encryption password
Copy the code

4.3 the test class

Create a new test class:

@SpringBootTest
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class EncryptAndDecrypt {
    private final StringEncryptor encryptor;
    @Value("${spring.mail.username}")
    private String username;
    @Value("${spring.mail.password}")
    private String password;

    @Test
    public void encrypt(a)
    {
        System.out.println(encryptor.encrypt(username));
        System.out.println(encryptor.encrypt(password));
    }

    @Test
    public void decrypt(a)
    { System.out.println(username); System.out.println(password); }}Copy the code

4.4 Obtaining ciphertext

Suppose the plaintext is as follows:

Run encrypt to display the following output:

4.5 Replacing plaintext

To replace plain text with the prefix ENC(and suffix) :

4.6 test

To get the plaintext, run decrypt directly and output:

That completes the encryption.

5 source

Java version:

  • Github
  • Yards cloud
  • CODECHINA

Kotlin version:

  • Github
  • Yards cloud
  • CODECHINA