Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 未在@Async注释方法中发送电子邮件_Java_Spring_Spring Boot_Email - Fatal编程技术网

Java 未在@Async注释方法中发送电子邮件

Java 未在@Async注释方法中发送电子邮件,java,spring,spring-boot,email,Java,Spring,Spring Boot,Email,我正在尝试为用户实现一个下载文件的功能。一般工作流程如下: 用户单击前端的下载按钮 后端将从请求接收下载信息,从数据库获取数据,然后生成zip文件 该文件将被上传到云存储中(本例中为谷歌) 将向用户发送一封带有签名URL的电子邮件,以便从云下载zip文件 所有步骤2、3和4都将在带有@Async注释的方法中执行。 问题是,如果我重新启动后端服务器并只发送一个下载请求,则一切正常,这意味着可以接收电子邮件。 但是,它在发送更多下载请求后不起作用。 不再发送电子邮件。没有错误,没有警告,但所有需要的

我正在尝试为用户实现一个下载文件的功能。一般工作流程如下:

  • 用户单击前端的下载按钮
  • 后端将从请求接收下载信息,从数据库获取数据,然后生成zip文件
  • 该文件将被上传到云存储中(本例中为谷歌)
  • 将向用户发送一封带有签名URL的电子邮件,以便从云下载zip文件
  • 所有步骤2、3和4都将在带有@Async注释的方法中执行。 问题是,如果我重新启动后端服务器并只发送一个下载请求,则一切正常,这意味着可以接收电子邮件。 但是,它在发送更多下载请求后不起作用。 不再发送电子邮件。没有错误,没有警告,但所有需要的数据都正确接收,只是没有发送电子邮件。

    有人知道它有什么问题吗

    我的电子邮件发件人:

    public class AbstractEmailSender {
    
        public MimeMessage mimeMessage;
        public MimeMessageHelper mimeMessageHelper;
        public JavaMailSender javaMailSender;
        private final String SENDER = MY_SEND_EMAIL_ADDRESS;
        public final String USER_NAME_KEY = "username";
    
        public AbstractEmailSender(JavaMailSender javaMailSender) throws MessagingException {
    //        this.javaMailSender = new JavaMailSenderImpl();
            this.javaMailSender = javaMailSender;
            this.doInitialization();
        }
    
        public void doInitialization() throws MessagingException {
            this.mimeMessage = this.javaMailSender.createMimeMessage();
            this.mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
        }
    
        public void setEmailContext(String receiver, String subject) throws MessagingException {
            this.mimeMessageHelper.setSubject(subject);
            this.mimeMessageHelper.setFrom(SENDER);
            this.mimeMessageHelper.setTo(receiver);
        }
    }
    
    @Component
    public class DownloadDataSuccessEmailSender extends AbstractEmailSender implements MailService{
    
        private final TemplateEngine templateEngine;
        private final static String DOWNLOAD_DATA_SUCCESS_EMAIL_SUBJECT = XXXXXX;
        private final static String SIGNED_URL_KEY = "signedUrl";
        private final static String DOWNLOAD_EMAIL_TEMPLATE_NAME = "downloadDataSuccessEmail.html";
        private static final Logger logger = LogManager.getLogger(DownloadDataSuccessEmailSender.class);
    
    
        public DownloadDataSuccessEmailSender(JavaMailSender javaMailSender, TemplateEngine templateEngine) throws MessagingException {
            super(javaMailSender);
            this.templateEngine = templateEngine;
        }
    
        @Override
        public void sendEmailWithSignedUrlToDownloadFile(URL signedUrl, String username, String receiver) {
            // print the result to make sure all data are processed correctly, nothing wrong with 
            //this step
            System.out.println(signedUrl);
            System.out.println(username);
            System.out.println(receiver);
            try{
                super.setEmailContext(receiver, DOWNLOAD_DATA_SUCCESS_EMAIL_SUBJECT);
                Context context = new Context();
                context.setVariable(this.USER_NAME_KEY, username);
                context.setVariable(SIGNED_URL_KEY, signedUrl);
                String email = this.templateEngine.process(DOWNLOAD_EMAIL_TEMPLATE_NAME, context);
                this.mimeMessageHelper.setText(email, true);
                this.javaMailSender.send(mimeMessage);
            }catch (MailException | MessagingException e) {
                logger.error("Email with download data error: ", e);
                throw new EmailSendException(ErrorInfo.EMAIL_SEND_EXCEPTION.getCode(), ErrorInfo.EMAIL_SEND_EXCEPTION.getMessage());
            }
        }
    }
    
    
    电子邮件配置文件:

    spring:
      mail:
        host: smtp.gmail.com
        username: MY_EMAIL_ADDRESS
        password: MY_PASSWORD
        properties.mail.smtp:
          auth: true
          connectiontimeout: 60000
          timeout: 60000
          writetimeout: 50000
          starttls.enable: true
        port: 587
        protocol: smtp
      thymeleaf:
        prefix: classpath:/templates/
    
    处理所有逻辑的异步方法

    @Override
        @Async
        @Transactional(timeout = DOWNLOAD_DATA_TRANSACTION_TIME_LIMIT)
        public void downloadFile(SearchQuery query, DownloadRequestRecord downloadRecord){
            String username = downloadRecord.getUsername();
            String emailAddress = this.userService.getUserEmailAddressByUsername(username);
            try{
                // here ignore the parts to get data from database and generate zip file and check if the file is uploaded to cloud space successfully here
                // ......
                if (uploadFile == null) { // check if file exists
                    logger.error("File: {} does not exist in cloud!", zipFileName);
                    downloadRecord.setSuccess(0);
                    this.downloadDataFailMessageEmailSender.sendEmailWithDownloadDataFail(emailAddress, username, downloadRecord.getQuery(), downloadRecord.getDownloadTime()); // send email to inform user the download is fail
                } else {
    // file exists, generate signed URL and send email with download link
                   this.downloadDataSuccessEmailSender.sendEmailWithSignedUrlToDownloadFile(signedUrl, username, emailAddress);
                    downloadRecord.setSuccess(1);
                }
            } catch (IOException | EmailSendException ex) {
                logger.error("Exception from downloading data: ", ex);
                downloadRecord.setSuccess(0);
            } finally {
                this.userService.recordDownloadHistoryOfUser(downloadRecord);
            }
        }
    
    我的线程池配置

    @Configuration
    public class AsyncConfig implements AsyncConfigurer {
    
        private static final int CORE_POOL_SIZE = 6;
        private static final int MAX_POOL_SIZE = 10;
        private static final int QUEUE_CAPACITY = 100;
        private static final String THREAD_NAME_PREFIX = "ThreadPoolTaskExecutor-";
        private static final Logger logger = LogManager.getLogger(AsyncConfig.class);
    
        @Override
        public Executor getAsyncExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(CORE_POOL_SIZE);
            executor.setMaxPoolSize(MAX_POOL_SIZE);
            executor.setQueueCapacity(QUEUE_CAPACITY);
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
            executor.initialize();
            return executor;
        }
    
        @Override
        public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
            return new AsyncUncaughtExceptionHandler() {
                @Override
                public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
                    logger.error("ERROR: ", throwable);
                }
            };
        }
    }
    

    在sendEmailWithSignedUrlToDownloadFile中,使用

    MimeMessage MimeMessage=mailssender.createMimeMessage()


    而不是将一个MimeMessage实例作为超级类的成员

    谢谢!现在可以了。你能解释一下为什么会这样吗?