発表
発表順
- 株式会社植山精米店 東中津支部
- RogiLab.
- 株式会社ホクティマスプライム
- 4
- 猋
Java/TDD/Spring Boot2/Backlog/Gitを使ったWebアプリ開発
発表順
プロジェクトを右クリックして[実行]-[Spring Boot アプリケーション]を選択することでWebアプリケーションを起動できる。
が。
[実行]のサブメニューから[SpringBootアプリケーション]が消えてしまうことがある。
その場合は、[実行]-[mvn ビルド…]を選択し、ゴールに「spring-boot:run」と入力して「実行」をクリックする。
※[実行]-[Spring Boot アプリケーション]を選択するとバックグラウンドで「mvn spring-boot:run」コマンドが実行されている。
以下の手順で、課題のコメントに「リビジョン詳細へのリンク」を追加する。
競合で困らないように、ときどきプルしよう。
競合が発生したら、
競合したファイルに対するマージ作業(編集)を行い、[チーム]-[索引に追加]する。
プルしてみる。
プルできれば、ローカルでの変更箇所をプッシュする。
プルできなかったら、プルできない原因を解決する。
エラーメッセージを見て、なぜプルできないのかを確認する。
毎回行うこと。
まずは、ロバストネス図に書いた画面遷移を全員で協力して完成する。
すべての画面遷移ができているという達成感が重要。
画面遷移ができてから、内部の作りこみを始める。
前回の課題が終わってない人は、課題が難しすぎるかどうか考えて、難しいのなら課題を分割する。
前回の課題を完了している人は、新しい課題をBacklogに登録してから着手する。
画像ファイル、CSS、JavaScriptなどの静的ファイルを置く方法
Spring Boot では、src/main/resources/static フォルダにそれらのファイルを配置する。
ログインしなくてもアクセスできるように、WebSecurityConfig に以下のコードを追加する。
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/images/**",
"/css/**",
"/js/**");
}
これから12月までチーム開発を行い、1月に作ったものを発表してもらう。
チーム開発ではツールとしてBacklogを使う。
どういうアプリケーションを作るか話し合おう!
などなど。
課題の採点
tweeterプロジェクトに以下の機能を実装する。
トップページ・マイページ・新規ユーザー登録ページ・ログインページを適切に行き来できること。
ログインページとマイページのリンクを作成。
ログインしているユーザーのアカウントで投稿できる。
ログインしているユーザーが、自分のプロフィールを編集できる。
自分で投稿したツイートを削除できる。
プロフィールと、自分の投稿だけを表示する。
トップページにアクセスしたら全ユーザーのすべてのツイートを時系列(新しい順)で表示する。
トップページとマイページでのツイート一覧で、ツイートの見た目をTwitterっぽくする。
MyController.java
@RequestMapping(value = "/tweet", method = RequestMethod.POST)
public ModelAndView tweet(ModelAndView mav,
@ModelAttribute("tweet") @Validated Tweet tweet,
Errors errors,
Principal p) {
if (errors.hasErrors()) {
mav.setViewName("mypage");
mav.addObject("msg", "エラーです");
return mav;
}
return new ModelAndView("redirect:/mypage");
}
どのような情報がTweetに入っているかを確認するため、TweetにtoString()メソッドを追加する。
Tweet.java
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder
.append("Tweet [id=").append(id)
.append(", content=").append(content)
.append(", time=").append(time)
.append(", profile=").append(profile)
.append("]");
return builder.toString();
}
コントローラからTweetをコンソールに出力してみる。
MyContoller.java
@RequestMapping(value = "/tweet", method = RequestMethod.POST)
public ModelAndView tweet(ModelAndView mav,
@ModelAttribute("tweet") @Validated Tweet tweet,
Errors errors,
Principal p) {
if (errors.hasErrors()) {
mav.setViewName("mypage");
mav.addObject("msg", "エラーです");
return mav;
}
System.out.println(tweet);
return new ModelAndView("redirect:/mypage");
}
Tweetに現在時刻とProfileを設定する。
@RequestMapping(value = "/tweet", method = RequestMethod.POST)
public ModelAndView tweet(ModelAndView mav,
@ModelAttribute("tweet") @Validated Tweet tweet,
Errors errors,
Principal p) {
if (errors.hasErrors()) {
mav.setViewName("mypage");
mav.addObject("msg", "エラーです");
return mav;
}
Optional<Profile> data = repository.findByUsername(p.getName());
tweet.setProfile(data.get());
tweet.setTime(new Date());
System.out.println(tweet);
return new ModelAndView("redirect:/mypage");
}
Tweetをデータベースに保存するために、リポジトリを作成する。
TweetRepository.java
package jp.abc;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TweetRepository extends JpaRepository<Tweet, Long> {
}
リポジトリを作成したので、コントローラからデータベースに保存する。
リポジトリをインスタンス変数として追加し、@AutowiredアノテーションをつけてDIしてもらう。
MyController.java
@Controller
public class MyController {
@Autowired
private JdbcUserDetailsManager userManager;
@Autowired
private ProfileRepository repository;
@Autowired
private TweetRepository tweetRepository;
@RequestMapping(value = "/tweet", method = RequestMethod.POST)
public ModelAndView tweet(ModelAndView mav,
@ModelAttribute("tweet") @Validated Tweet tweet,
Errors errors,
Principal p) {
if (errors.hasErrors()) {
mav.setViewName("mypage");
mav.addObject("msg", "エラーです");
return mav;
}
Optional<Profile> data = repository.findByUsername(p.getName());
tweet.setProfile(data.get());
tweet.setTime(new Date());
System.out.println(tweet);
tweetRepository.saveAndFlush(tweet);
return new ModelAndView("redirect:/mypage");
}
mypage にツイート一覧を表示できるように、コントローラからModelAndViewに渡しておく。
MyController.java
@RequestMapping(value = "/mypage")
public ModelAndView top(ModelAndView mav, Principal p) {
mav.setViewName("mypage");
mav.addObject("username", p.getName());
Optional<Profile> data = repository.findByUsername(p.getName());
Profile profile;
if (!data.isPresent()) {
profile = new Profile();
profile.setUsername(p.getName());
repository.saveAndFlush(profile);
} else {
profile = data.get();
}
mav.addObject("profile", profile);
List<Tweet> list = tweetRepository.findAll();
mav.addObject("datalist", list);
return mav;
}
mypage にツイート一覧を表示する。
mypage.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>login</title>
</head>
<body>
<h1>マイページ</h1>
<p>ようこそ、<span th:text="${username}"></span>さん!</p>
<p th:text="${profile.username}"></p>
<form th:action="@{/tweet}" th:object="${tweet}" method="post">
<textarea name="content" cols="40" rows="10"></textarea>
<br />
<input type="submit" value="ツイートする" />
</form>
<form th:action="@{/logout}" method="post">
<input type="submit" value="ログアウト" />
</form>
<hr />
<table>
<tr>
<th>名前</th><th>日時</th><th>投稿内容</th>
</tr>
<tr th:each="obj : ${datalist}">
<td th:text="${obj.profile.username}"></td>
<td th:text="${obj.time}"></td>
<td th:text="${obj.content}"></td>
</tr>
</table>
</body>
</html>
前期提出課題にログイン認証機能を追加したものを提出課題とする予定なので、前期提出課題ができていない人は、取り組んでおくこと
本の編集と削除ができるようになったら、本棚の編集と削除もやってみよう!