Java Second Kill System Practical Series ~Developing Universal Mail Sending Service

Posted by zoozle on Tue, 30 Jul 2019 12:13:40 +0200

Summary:

This blog is the ninth in the "Java Second Kill System Practical Series Articles". In this article, we will continue to improve the core processing logic of the second kill system, that is, the business logic of "User Second Kill to Snap Money"! In this paper, we will develop a general email service based on JavaMail service to send email notification message, and integrate it with RabbitMQ asynchronous message sending logic which has been implemented in the previous chapter. We will completely realize that "after the success of the second kill, asynchronous email notification message is sent to the user's mailbox for notification. Payment as soon as possible!

Contents:

For sending mail service, I believe you are no strangers. In this blog, we will develop a general sending mail service for asynchronous sending mail messages to users after successful second killing.

(1) In the same way, first we need to add the dependency of sending mail service. The dependency version number is 1.5.7.RELEASE, which is the same as SpringBook version number, as follows:

<!--mail-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
    <version>${spring-boot.version}</version>
</dependency>

Next, we need to add the additional support configuration information needed for the "Send Mail Service" in the application.properties configuration file:

#Send mail configuration
spring.mail.host=smtp.qq.com
spring.mail.username=1974544863@qq.com
spring.mail.password=cmtvsjvhonkjdaje

spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

mail.send.from=1974544863@qq.com

mail.kill.item.success.subject=Successful commodity snap-up
mail.kill.item.success.content=Hello, you have successfully snapped up the goods.: <strong style="color: red">%s</strong> ,Copy the link and open it on a new page in the browser to see the snap-up details: ${system.domain.url}/kill/record/detail/%s,And please complete the payment of the order within 1 hour, the overtime will expire the order oh! Wish you a happy life!

In this second kill system, we use QQ mailbox as the main mailbox account, and the corresponding SMTP server also uses QQ mailbox! Among them, spring.mail.password refers to the "key" (authorization code) that Tencent officially gave when opening POP3/SMTP service in the background of QQ mailbox. Here, Debug contributed the above key to authorization code for you to use. But in the enterprise production environment, in fact, it is necessary to apply for a master mailbox account. How to apply, I will not repeat here!

(2) Next, we can show our hand! In MailService, we have developed two functions for sending mail: one is to send simple text (that is, plain text, rigid, cold air) and the other is to send fancy text with HTML tags (that is, styled, funny and warm), as follows:

//Universal Mail Delivery Service
@Service
@EnableAsync
public class MailService {
    private static final Logger log= LoggerFactory.getLogger(MailService.class);

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private Environment env;

    //Send a simple text file
    @Async
    public void sendSimpleEmail(final MailDto dto){
        try {
            SimpleMailMessage message=new SimpleMailMessage();
            message.setFrom(env.getProperty("mail.send.from"));
            message.setTo(dto.getTos());
            message.setSubject(dto.getSubject());
            message.setText(dto.getContent());
            mailSender.send(message);

            log.info("Send a simple text file-Successful delivery!");
        }catch (Exception e){
            log.error("Send a simple text file-Abnormal: ",e.fillInStackTrace());
        }
    }

    //Send fancy mail
    @Async
    public void sendHTMLMail(final MailDto dto){
        try {
            MimeMessage message=mailSender.createMimeMessage();
            MimeMessageHelper messageHelper=new MimeMessageHelper(message,true,"utf-8");
            messageHelper.setFrom(env.getProperty("mail.send.from"));
            messageHelper.setTo(dto.getTos());
            messageHelper.setSubject(dto.getSubject());
            messageHelper.setText(dto.getContent(),true);

            mailSender.send(message);
            log.info("Send fancy mail-Successful delivery!");
        }catch (Exception e){
            log.error("Send fancy mail-Abnormal: ",e.fillInStackTrace());
        }
    }
}

MailDto class mainly encapsulates the field information needed when sending mail, such as recipient, mail title, mail content and so on. (It presents the important features of object-oriented)! Its source code is as follows:

/**Unified encapsulation of field information needed to send mail
 * @Author:debug (SteadyJack)
 * @Date: 2019/6/22 10:11
 **/
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class MailDto implements Serializable{
    //Mail Subject
    private String subject;
    //Mail content
    private String content;
    //Receiver
    private String[] tos;
}

(3) Finally, the logic of "sending mail service" is integrated into the receiving message logic of Rabbit Receiver Service, which is "RabbitMQ general message receiving service class". The following is the following:

@Autowired
private MailService mailService;

@Autowired
private Environment env;

/**
 * Second Kill Asynchronous Mail Notification - Receive Messages
 */
@RabbitListener(queues = {"${mq.kill.item.success.email.queue}"},containerFactory = "singleListenerContainer")
public void consumeEmailMsg(KillSuccessUserInfo info){
    try {
        log.info("Second Kill Asynchronous Mail Notification-receive messages:{}",info);

        //TODO: Real email...
        //Simple text
        //MailDto dto=new MailDto(env.getProperty("mail.kill.item.success.subject"), "This is the test content", new String[]{info.getEmail()};
        //mailService.sendSimpleEmail(dto);

        //Fancy text
        final String content=String.format(env.getProperty("mail.kill.item.success.content"),info.getItemName(),info.getCode());
        MailDto dto=new MailDto(env.getProperty("mail.kill.item.success.subject"),content,new String[]{info.getEmail()});
        mailService.sendHTMLMail(dto);

    }catch (Exception e){
        log.error("Second Kill Asynchronous Mail Notification-receive messages-Abnormal:",e.fillInStackTrace());
    }
}

(4) At this point, we will introduce the code of the general mail delivery service, and then we will enter the testing section. Click on "snap-up". If the user succeeds in second killing, the back end of the system will enter an order after second killing in the database. At the same time, the mailbox corresponding to "mailbox field value" in the user table will receive an email, as shown in the following figure:

Well, the happy time is always short, so we'll introduce it here in this article. In the next blog post, we will continue our journey of "Second Kill System Actual Warfare"!

Supplement:

1. At present, the whole construction and code battle of this second kill system have been completed. The complete source code database address can be downloaded here: https://gitee.com/steadyjack/SpringBoot-SecondKill Remember Fork and Star!!!

2. Because the updates of the corresponding blogs may not be very fast, if you want to get a quick start and a real-world system, you can consider contacting Debug to get the complete video tutorial of the "Java Secondary Killing System" (the course is charged!). Of course, you can also click on the following link https://gitee.com/steadyjack/SpringBoot-SecondKill Contact Debug or join the corresponding technology exchange group for communication!

Topics: Java Spring RabbitMQ Database