代码之家  ›  专栏  ›  技术社区  ›  Alfredo Marin

为什么我的服务没有使用我的Spring@Bean?

  •  0
  • Alfredo Marin  · 技术社区  · 1 年前

    我正试图用给定的模板发送电子邮件,但当我调用“templateEngine.produce”时,它不会给出任何异常,但它不会处理模板,只返回一个带有模板名称的字符串

    我的POM依赖项:

    <dependencies>
        <!-- Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</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-amqp</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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    
        <!-- Spring Doc -->
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>2.1.0</version>
        </dependency>
    
        <!-- Eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    
        <!-- LOMBOK -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
        </dependency>
    </dependencies>
    

    我的配置:

    @Configuration
    public class EmailConfiguration {
    
        @Bean
        public SpringTemplateEngine springTemplateEngine() {
            SpringTemplateEngine templateEngine = new SpringTemplateEngine();
            templateEngine.addTemplateResolver(htmlTemplateResolver());
            return templateEngine;
        }
    
        @Bean
        public ClassLoaderTemplateResolver htmlTemplateResolver(){
            ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver();
            emailTemplateResolver.setPrefix("classpath:/templates/");
            emailTemplateResolver.setSuffix(".html");
            emailTemplateResolver.setTemplateMode(TemplateMode.HTML);
            emailTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
            return emailTemplateResolver;
        }
    }
    

    我的控制器:

        @PostMapping("/send")
        public boolean sendEmail(@RequestParam("lang") String language, @RequestBody EmailRequestDTO payload) throws NotifierEmailException {
            emailService.sendSimpleMailMessage(payload, language);
            return true;
        }
    

    我的服务:

    @Service
    public class EmailService {
    
        private static final String ENCODING = "UTF-8";
    
        private final JavaMailSender emailSender;
    
        public final TemplateEngine template = new SpringTemplateEngine();
    
        @Autowired
        public EmailService(JavaMailSender emailSender) {
            this.emailSender = emailSender;
        }
    
        public void sendSimpleMailMessage(EmailRequestDTO emailRequestDTO, String language) throws NotifierEmailException {
            try {
                var locale = Locale.forLanguageTag(language);
                // Prepare the evaluation context
                final Context thymeleafContext = new Context(locale);
                emailRequestDTO.getAttributes().forEach(thymeleafContext::setVariable);
    
                // Prepare message using a Spring helper
                final MimeMessage mimeMessage = emailSender.createMimeMessage();
                final MimeMessageHelper message = new MimeMessageHelper(mimeMessage, ENCODING);
                message.setSubject(emailRequestDTO.getSubject());
                message.setFrom(emailRequestDTO.getEmailFrom());
                message.setTo(emailRequestDTO.getEmailTo());
    
                // Create the HTML body using Thymeleaf
                /* This line here returns a string with the template name that I passed! */
                final String htmlContent = template.process("activationEmail.html", thymeleafContext);
                message.setText(htmlContent, true);
    
                // Send mail
                emailSender.send(mimeMessage);
            } catch (Exception exception) {
                throw new NotifierEmailException(HttpStatus.INTERNAL_SERVER_ERROR, exception.getMessage());
            }
        }
    }
    

    没有包含application.properties,因为我没有将其用于thymelaf。

    我的模板位置 enter image description here

    我执行时的日志(我在这里隐藏了一些数据):

    DATA
    354  Go ahead z15-20020aa785cf000000b006daa809584csm3243217pfn.182 - gsmtp
    Date: Sat, 27 Jan 2024 19:50:01 -0300 (BRT)
    From: [HIDDEN]
    To: [HIDDEN]
    Message-ID: <851717819.0.1706395805863@DESKTOP-MVK6CCP>
    Subject: Activation
    MIME-Version: 1.0
    Content-Type: text/html;charset=UTF-8
    Content-Transfer-Encoding: 7bit
    
    activationEmail.html
    .
    250 2.0.0 OK  1706395825 z15-20020aa785cf000000b006daa809584csm3243217pfn.182 - gsmtp
    DEBUG SMTP: message successfully delivered to mail server
    QUIT
    

    收到的电子邮件: enter image description here

    1 回复  |  直到 1 年前
        1
  •  1
  •   tgdavies    1 年前

    当您创建类型的Bean时 SpringTemplateEngine 在您的配置类中 @Service 不使用此bean:

    Service
    public class EmailService {
    
        private static final String ENCODING = "UTF-8";
    
        private final JavaMailSender emailSender;
    
        public final TemplateEngine template = new SpringTemplateEngine();
    
        @Autowired
        public EmailService(JavaMailSender emailSender) {
            this.emailSender = emailSender;
        }
    

    你的 template 字段用新创建的初始化 SpringTemplateEngine 实例,而您的构造函数只接受 JavaMailSender 例子

    您需要添加 TemplateEngine 参数,并删除的初始化 样板 领域

    所以你的 EamilService 看起来像:

    ...
        private final TemplateEngine template;
    
        @Autowired
        public EmailService(JavaMailSender emailSender, TemplateEngine templateEngine) {
            this.emailSender = emailSender;
            this.templateEngine = templateEngine;
        }
    ...
    

    作为 Javadoc for TemplateEngine 说,一个 模板引擎 没有 ItemplateResolver 配置将使用 StringTemplateResolver 这就解释了你看到的行为。