письмо на почту Spring

пытаюсь отправить письмо на почту не понимаю почему у меня ошибка введите сюда описание изображения

package com.tkr.blog.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.IContext;

import javax.naming.Context;

@Service
public class MailContentBuilder
{
    private TemplateEngine templateEngine;

    @Autowired
    public MailContentBuilder(TemplateEngine templateEngine)
    {
        this.templateEngine = templateEngine;
    }

    public String build(String message)
    {
        Context context = new Context();
        context.setVariable("message", message);
        return templateEngine.process("templates/blogs/emailTemplate", (IContext) context);
    }
}

введите сюда описание изображения

package com.tkr.blog.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Service;

@Service
public class MailerService
{
    @Autowired
    private JavaMailSender emailSender;

    @Autowired
    private MailContentBuilder mailContentBuilder;

    public void prepareAndSend(String recipient, String message,String subject,String from)
    {
        MimeMessagePreparator messagePreparator = mimeMessage ->
        {
            MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
            messageHelper.setFrom(from);
            messageHelper.setTo(recipient);
            messageHelper.setSubject(subject);
            messageHelper.setText(message);
            String content = mailContentBuilder.build(message);
            messageHelper.setText(content,true);
        };

        try {
            emailSender.send(messagePreparator);
        }catch (MailException e ){
            System.out.println("Error sending email");
        }
    }
}


Ответы (1 шт):

Автор решения: Михаил Ребров

Во-первых:
На Вас сама IDE ругается и просит Вас больше не пытаться создавать объекты из интерфейсов и абстрактных классов.
Интерфейсы лишь описывают каким условиям должен соответствовать класс, но они не реализует их.
Для этого нужно найти подходящую реализацию и уже на ее основе создать объект.

Во-вторых:

Далее вы пытаетесь вызвать метод TemplateEngine.process().
Он имеет такую сигнатуру:

public final String process(String template, org.thymeleaf.context.IContext context) { /** ...*/ }

Метод принимает два параметра:

  • строка с шаблоном
  • некий контекст, описанный интерфейсом org.thymeleaf.context.IContext

Давайте взглянем на исходный код данного интерфейса org.thymeleaf.context.IContext:

package org.thymeleaf.context;

import java.util.Locale;
import java.util.Set;

public interface IContext {
    Locale getLocale();

    boolean containsVariable(String var1);

    Set<String> getVariableNames();

    Object getVariable(String var1);
}

В нем объявлены методы с помощью которых можно:

  • узнать название переменных, находящихся в данном контексте;
  • получить данную переменную;
  • узнать есть ли интересующая нас переменная в контексте или нет;
  • и узнать локаль;

Всё!
Это все что нужно знать об этом контексте.
И что самое важное: он ни от кого не наследуется и ни с кем больше не связан.

А из этого следует что он и не связан с интерфейсом javax.naming.Context, который Вы упорно пытаетесь создать.
Упорно, потому что IDE также Вам подсказывала, что Вы делаете что-то не то.
Метод process(), отчаянно пытался сказать Вам что он не хочет принимать внутрь объект типа javax.naming.Context.
Но Вы решили не слушать его и привели совершенно чужеродный объект(который еще и не может быть создан) к требуемому интерфейсу org.thymeleaf.context.IContext и с молотком, и против воли всех объектов и методов, участвующих в процессе, таки вогнали одно в другое.

Что нужно было делать и как все это исправить? Нужно было просто посмотреть варианты импорта для класса Context и выбрать не первый попавшийся, а тот, который соответствует интерфейсу, который требует метод процесс. В вашем случае это скорее всего класс org.thymeleaf.context.Context

Соответственно Вам нужно заменить строку:

import javax.naming.Context;

на следующую:

import org.thymeleaf.context.Context;

Это все!

После этого Ваш код станет работать!
(Если больше нигде Вы не совершили других ошибок, естественно. Но это уже совсем другая история)

И пару советов:

  • Не бойтесь ошибок!
    Вы удивитесь, когда узнаете как много полезной информации они могут содержать. И зачастую, они подсказывают как именно можно разрешить данную ошибку. Во многих сообщениях об ошибках об этом написано прямым текстом.
    Поэтому не стоит их боятся - они Ваши друзья!
    Поверьте: если бы их не было, писать программы было бы гораздо сложнее!
  • Не бойтесь читать исходный код!
    Если Вы не понимаете как что-то происходит, если Вы не можете разобраться что куда и как нужно передавать: откройте исходный код классов, которые Вы используете и разберитесь с тем что там написано. Никакая документация, никакие ответы со stackoverflow и никакие туториалы с гайдами никогда не сравнятся по информативности с исходным кодом. И этот ресурс у Вас всегда под руками! Не стоит бояться лазить под капот каких-либо фреймворков. Поначалу возможно Вам будет тяжело, но чем дальше тем проще для Вас это будет. И чем раньше Вы начнете это практиковать, тем быстрее Вы освоите данную технологию и тем быстрее Вы разовьётесь как специалист.
→ Ссылка