SpringBootを使用してメール送信方法として、以下に記載する2つを紹介していきます。
- 直接インスタンスを作成する方法。
- DI(Dependency Injection)を使用する方法。
基本的には、DIを使用する方法で問題ないと思います。
ただし、メール送信方法(使用するメールサーバを変更する場合など)は、直接インスタンスを作成する方法を検討してもよいのかもしれません。
環境
検証に使用した環境/ライブラリを以下に記載します。
- Java:11
- SpringBoot:2.2.6
- Gradle:6.1
検証のテスト用に使用したライブラリを以下に記載します。
- JUnit:5.5.2
- GreenMail:1.5.11
メール送信のテストを実施するために「GreenMail」を使用します。テスト方法については、以下の記事も参考になると思います。
ビルドスクリプト
ビルドスクリプトとして使用する「build.gradle」を以下に記載します。
plugins {
id 'org.springframework.boot' version '2.2.6.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-mail'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'com.icegreen:greenmail:1.5.11'
}
test {
useJUnitPlatform()
}
メール送信方法
直接インスタンス作成する方法
メール送信時に、直接インスタンスを作成する送信する方法になります。
SpringBootの設定ファイル(application.properties、application.ymlなど)を使用しない方法になります。メールサーバーの設定などは個別に設定する必要があります。
メール送信のメインプログラム
メール送信のサンプルプログラムを以下に記載します。
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;
@Service
public class MailSenderInstanceService {
public void send() {
// 「メール送信」のクラスを直接作成する。
JavaMailSenderImpl impl = new JavaMailSenderImpl();
impl.setHost("localhost");
impl.setPort(3025);
// メール送信内容作成して設定する。
SimpleMailMessage message = new SimpleMailMessage();
message.setTo("to@example.com");
message.setFrom("from@example.com");
message.setSubject("てすと件名");
message.setText("てすと本文。");
// メール送信を実施する。
impl.send(message);
}
}
メール送信のテストプログラム
メール送信のサンプルプログラムのテストプログラムを以下に記載します。
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetupTest;
class MailSenderInstanceServiceTest extends MailSenderInstanceService {
private GreenMail greenMail;
@BeforeEach
public void before() {
this.greenMail = new GreenMail(ServerSetupTest.SMTP);
this.greenMail.start();
}
@AfterEach
public void after() {
this.greenMail.stop();
}
@Test
void testSend() throws Exception {
// メール送信のテストを実施する。
MailSenderInstanceService service = new MailSenderInstanceService();
service.send();
// メール送信のテスト結果の確認を実施する。
MimeMessage[] mimeMessages = this.greenMail.getReceivedMessages();
Assert.assertThat(1, Matchers.is(mimeMessages.length));
MimeMessage mimeMessage = mimeMessages[0];
Assert.assertThat(mimeMessage.getRecipients(RecipientType.TO)[0].toString(), Matchers.is("to@example.com"));
Assert.assertThat(mimeMessage.getFrom()[0].toString(), Matchers.is("from@example.com"));
Assert.assertThat(mimeMessage.getSubject(), Matchers.is("てすと件名"));
Assert.assertThat(mimeMessage.getContent().toString(), Matchers.is("てすと本文。"));
}
}
DI(Dependency Injection)を使用する方法
メール送信をDI(Dependency Injection)を使用して送信する方法になります。
SpringBootの設定ファイル(application.properties、application.ymlなど)をきちんと指定していない場合は、以下に記載する例外が発生するため注意してください。
java.lang.IllegalStateException: Failed to load ApplicationContext
例外発生時の問題として、メール送信に関連する設定が見つかないことについての原因が出力されます。
Description:
Field mailSender in xxxx required a bean of type 'org.springframework.mail.MailSender' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.mail.MailSender' in your configuration.
SpringBoot設定ファイル
メール送信に関連する設定は、最低限以下に記載する設定だけでメール送信を実行することができます。記載している例は、検証のテストに使用するための設定になります。
spring.mail.host=localhost
spring.mail.port=3025
メール送信のメインプログラム
メール送信のサンプルプログラムを以下に記載します。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;
@Service
public class MailSenderService {
@Autowired
MailSender mailSender;
public void send() {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo("to@example.com");
message.setFrom("from@example.com");
message.setSubject("てすと件名");
message.setText("てすと本文。");
this.mailSender.send(message);
}
}
メール送信のテストプログラム
メール送信のサンプルプログラムのテストプログラムを以下に記載します。
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetupTest;
@RunWith(SpringRunner.class)
@SpringBootTest
class MailSenderInjectionServiceTests {
@Autowired
MailSenderInjectionService mailSenderService;
private GreenMail greenMail;
@BeforeEach
public void before() {
this.greenMail = new GreenMail(ServerSetupTest.SMTP);
this.greenMail.start();
}
@AfterEach
public void after() {
this.greenMail.stop();
}
@Test
void testSend() throws Exception {
// メール送信のテストを実施する。
this.mailSenderService.send();
// メール送信のテスト結果の確認を実施する。
MimeMessage[] mimeMessages = this.greenMail.getReceivedMessages();
Assert.assertThat(1, Matchers.is(mimeMessages.length));
MimeMessage mimeMessage = mimeMessages[0];
Assert.assertThat(mimeMessage.getRecipients(RecipientType.TO)[0].toString(), Matchers.is("to@example.com"));
Assert.assertThat(mimeMessage.getFrom()[0].toString(), Matchers.is("from@example.com"));
Assert.assertThat(mimeMessage.getSubject(), Matchers.is("てすと件名"));
Assert.assertThat(mimeMessage.getContent().toString(), Matchers.is("てすと本文。"));
}
}
まとめ
SpringBootを使用してのメール送信を方法を紹介しました。
SpringBootのバージョンにより使用方法などが異なることがあります。使用する場合はライブラリのバージョンを確認するようにしてください。