spring.svg

【Spring Boot】メール送信

SpringBoot

導入

build.gradle に以下を追加します。

Gradle
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.apache.velocity:velocity:1.7'
compile('org.springframework.boot:spring-boot-starter-mail')
compile('org.apache.velocity:velocity:1.7')

velocityは、後に説明するメールテンプレート用のもので、使用しない場合は必要ありません。

設定

application.yml(application.properties)に SMTP の情報を設定します。

application.yml
spring:
  mail:
    host: smtp-server
    port: smtp-port

GMail などを使用する場合は追加の設定が必要になります。

application.yml
spring:
  mail:
    host: smtp.gmail.com
    port: 587
    username: xxxx@gmail.com
    password: password
    properties:
      mail:
        smtp:
          auth: true
          starttls.enable: true

メール送信

テキスト

メール送信を行うには、JavaMailSenderを使用します。

また送信アドレスや件名、本文などの送信情報は、MimeMessageHelperを介してMimeMessageに設定します。

@Service
public class SampleDataService {
  @Autowired
  private JavaMailSender sender;

  public void sendMail() {
    MimeMessage message = sender.createMimeMessage();
    try {
      //送信情報設定
      MimeMessageHelper helper = new MimeMessageHelper(message, true);
      helper.setFrom("xxxxx@xxx.xx");
      helper.setTo("xxxxx@xxx.xx");
      helper.setCc("xxxxx@xxx.xx");
      helper.setBcc("xxxxx@xxx.xx");
      helper.setSubject("件名");
      helper.setText("本文");
      //メール送信
      sender.send(message);
    } catch(MessagingException e) {
      e.printStackTrace();
    }
  }
}

setTo()setCcsetBccは可変長引数になっており、送信先が複数ある場合はカンマ区切りで設定します。

HTML

HTML メールを送信する場合は、setTextの第一引数にテキストメール、第二引数に HTML メールの本文を設定します。

helper.setText("本文", "<span style='color: red'>本文</span>");

通常は HTML メールが表示され、送信先が HTML メールに対応していない場合はテキストメールが表示されます。

添付

メールにファイルを添付する場合、addAttachment()を使用します。 以下はローカルにあるファイルを添付に設定する例です。

FileSystemResource resource = new FileSystemResource("ファイルパス");
helper.addAttachment("filename", resource);

第一引数にはファイル名を、第二引数にはファイルのリソースを設定します。 第二引数に設定できるのは、DataSourceFileInputStreamSourceです。

複数ファイルがある場合は、その数だけaddAttachment()を実行するだけです。

Velocity

メール本文のテンプレートとして Velocity を使用します。

Velocity の詳細は割愛します。以下のサイトを参考にしてください。

TECHSCORE

テンプレートの作成

src/main/resources/templatessample.vmを作成します。

ID: ${id}
名前: ${lastName} ${firstName}
年齢: ${age}

${param}はパラメーターとなり、外部からの値を設定します。

DI コンテナへの登録

上記のテンプレートを読み込むには、VelocityEngineを使用します。

テンプレートファイルをsrc/mail/resourcesからの相対パスで読み込みたい場合、 以下のようにVelocityEngineのインスタンスを生成します。

Properties prop = new Properties();
prop.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
prop.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
VelocityEngine velocity = new VelocityEngine(prop);

ただ、このインスタンスの生成を毎回記述するのは手間なので、DI コンテナを使用します。

DI コンテナへ登録するために、@Configurationを付与したクラスを作成します。 これにより、@Autowiredで依存性の注入が行われます。

@Configuration
public class ApiConfig {

  @Bean
  public VelocityEngine velocityEngine() {
    Properties prop = new Properties();
    prop.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
    prop.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
    return new VelocityEngine(prop);
  }
}

テンプレートの読み込み

以下のようにして、テンプレートを読み込みメール本文を作成します。

パラメーターの設定にはVelocityContextを使用し、put()でパラメーターと値のセットを設定します。

@Service
public SampleDataService {
  @Autowired
  private JavaMailsender sender;

  @Autowired
  private VelocityEngine velocity;

  //...

  private String getTextBody() {
    //パラメーター定義
    VelocityContext context = new VelocityContext();
    context.put("id", "000001");
    context.put("firstName", "taro");
    context.put("lastName", "yamada");
    context.put("age", 20);

    //テンプレートの読み込み
    StringWriter writer = new StringWriter();
    velocity.mergeTemplate("templates/sample.vm", "UTF-8", context, writer);
    return writer.toString();
  }
}

結果として以下の本文が作成されます。

ID: 000001
名前: yamada taro
年齢: 20