Spring bootでメールフォームの実装
何故Spring bootなのか
自社のHP開発で使ったからです。
何故メールフォームなのか
僕が担当した箇所だからです。
開発環境
仕様について
アプリの仕様はこんな感じ。
- 入力内容は、「メールアドレス・名前・性別・問い合わせ内容」の3つ。入力のバリデーションは無し。
- DBに情報を残すといったことは今回はなし。
- 画面遷移は下記の感じ。
- 入力画面
- 入力内容の確認画面
- 管理者のメールアドレスに入力内容の送信し、完了画面へ遷移
プロジェクトを作る
実際の業務開発では、Backlogのgitからプルして、Mavanプロジェクトとして置き換えて… (ここは、実は地味に1時間くらい躓きました。プロジェクトを右クリック =>実行 を見ると、実行の構成とか書いてあって「全然起動しねーじゃねぇか!」ってなってました。) ということをしていたのですが、今回は、全部自分でやるので、プロジェクトを作るところからはじめます。
下記の方法で、新しいプロジェクトを作成。適当にプロジェクト名を決める。
- パッケージエクスプローラ内右クリック => 新規 => プロジェクト
- Spring boot => Spring スタータープロジェクト
会社では、Mavenを使ってたけど、なんかgradleのほうが、いろいろ情報が載ってて便利そうだし、練習も兼ねてgradleを選択。
とりあえず、参考サイトをみつつ、初期ライブラリの選択。別に後からgradleとかMavenとか弄れば追加できるっぽいから、今回必要そうなものだけ。
プロジェクトが出来たら起動テスト。問題なし。
フォームを作る。
ハロワとか一応やったけど、面倒なので、書くのは省略。メールフォームのクラスから書きます。
package com.hatenablog.threeroots.model; public class MailForm{ private String mail; private String name; private String sex; private String content; //getter & setter }
Formの仕様的に全部Stringで取得したほうが楽そうだから、とりあえずコレで。改善の余地、あり。 これを、modelというpackageを作って入れる。
コントローラーを作る。
この程度だったらやらなくてもいいんだろうけど、一応controllerってパッケージを作ってその中に作る。
package com.hatenablog.threeroots.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import com.hatenablog.threeroots.model.MailForm; import com.hatenablog.threeroots.service.SendMailService; @Controller public class ContactController { @Autowired private SendMailService sendMailService; @GetMapping("/") public String index(Model model){ return "index"; } @PostMapping("/confirm") public String confirm(@ModelAttribute MailForm mailForm, Model model){ model.addAttribute("mailForm", mailForm); return "confirm"; } @PostMapping("/complete") public String complete(@ModelAttribute MailForm mailForm){ sendMailService.send(mailForm); return "complete"; } }
送信実行部分(SendMailService)を作る。
メールの送信方法には、いくつかやり方があるようだけど、一番簡単そうだったspring-boot-starter-mailを使用した。
実装の前に、必要な設定をする。
1. build.gradleに依存関係の追加
compile('org.springframework.boot:spring-boot-starter-mail')
2. application.ymlの追記
spring.mail.host=smtp.gmail.com spring.mail.port=587 spring.mail.username=hogehoge@gmail.com spring.mail.password=password spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true
ちなみに、ここの記法を、なぜか変な感じにしていたせいで、ビルドエラーを吐いていた。基本コピペでやってたから、どっかのサイトが多分間違ってるか、僕が勘違いして変な情報を貼り付けた。
実装してみる
serviceパッケージを作って実装。
package com.hatenablog.threeroots.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.MailSender; import org.springframework.mail.SimpleMailMessage; import org.springframework.stereotype.Service; import com.hatenablog.threeroots.model.MailForm; @Service public class SendMailService{ @Autowired private MailSender mailSender; public void send(MailForm mailForm) { SimpleMailMessage msg = new SimpleMailMessage(); msg.setFrom(mailForm.getMail()); msg.setTo("hogehoge@hogehoge.com"); // 管理者アドレス msg.setSubject("お問い合わせがありました"); msg.setText(makeContent(mailForm)); mailSender.send(msg); } public String makeContent(MailForm mailForm){ return "名前: " + mailForm.getName() + "\n" + "性別: " + mailForm.getSex() + "\n" + "問い合わせ内容: " + mailForm.getContent(); } }
フロント画面を作る
超簡単につくる。
入力画面
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <div> <form action="/confirm" method="post"> <div>お名前</div> <div> <input type="text" id="name" name="name"> </div> <div>メールアドレス</div> <div> <input type="email" id="mail" name="mail"> </div> <div> <input type="radio" name="sex" id="sex" value="男性" checked="checked" />男性 <input type="radio" name="sex" id="sex" value="女性" />女性 </div> <div> <textarea id="content" name="content" rows="3" cols="">お問い合わせ内容</textarea> </div> <div> <input type="submit" value="送信する"> </div> </form> </div> </html>
普通にフォームで受け取った内容をpostで送るだけ。ここは見たまま。
確認画面
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <div th:object="${mailForm}"> <form action="/complete" method="post"> <div><span th:text="*{name}"></span></div> <div><span th:text="*{mail}"></span></div> <div><span th:text="*{sex}"></span></div> <div><span th:utext="${mailForm.content} ? ${#strings.replace(mailForm.content, T(java.lang.System).getProperty('line.separator'), '<br />')}"></span><div> <div> <input type="hidden" th:field="*{name}" value="*{name}"> <input type="hidden" th:field="*{mail}" value="*{mail}"> <input type="hidden" th:field="*{sex}" value="*{sex}"> <input type="hidden" th:field="*{content}" value="*{content}"/> <input type="submit" value="上記内容で送信する"> </div> </form> </div> </html>
こっちが、割と作ってるときに詰まりました。理由として
- th:text=で変数を入力するときには、objectを設定しなければならない。今回は上部階層のdivタグで設定したけど、"${contactForm.name}"みたいにも書ける。
- completeのServiceに値を受け渡すためにhiddenで値をもう一度受け渡し直さなければならない。このことに気づかず、ずっとNULLのメールを送りまくってた。
- 改行情報をHTMLで表示する際に、改行タグに変換しなければならなかった。これは、ぐぐったらthymeleaf側で頑張れそうだったので、表側で処理。
完了画面
完了しました。
もはやhtmlですらないけど、画面表示よりも、メールが送られているが大事なのでこれで良い。
テストしてみる
送信できました。 とりあえず今回はここまで。
今後の課題
- バリデーションの設定
- フロント実装時、bootstrapを使ってみる
参考にしたもの
Spring Bootでメール送信する方法 | ホームページ制作のサカエン(墨田区)
SpringBoot + JPA + Thymeleafで簡単なCRUDを作る①~HelloWorldまで~
Spring Boot でメール送信する Web アプリケーションを作る ( その15 )( Thymeleaf を利用して HTML メールを送信する2 ) - かんがるーさんの日記