Spring Boot によるWebアプリ開発

2021システム開発実習

SpringBoot

MusicPlayerをWebアプリにする – 2

投稿日:

個別のプレイリストの画面を表示できるようにする。

まず、プレイリストの一覧をテーブルで表示しているところの、プレイリスト名をリンクに変更する。

<h3>プレイリスト</h3>
<table>
	<tr>
		<th>ID</th>
		<th>名前</th>
	</tr>
	<tr th:each="playlist : ${playlists}">
		<td th:text="${playlist.id}"></td>
		<td><a th:href="@{'/playlist/' + ${playlist.id}}" th:text="${playlist.name}"></a></td>
	</tr>
</table>

IndexController で、URL /playlist/{id} を受け付けるようにする。

	@RequestMapping(value="/playlist/{id}", method=RequestMethod.GET)
	public ModelAndView playlist(ModelAndView mav,
			@PathVariable long id) {
		Optional<PlayList> r = playListRepository.findById(id);
		PlayList pl = r.get();
		mav.addObject("playlist", pl);
		mav.setViewName("playlist");
		return mav;
	}

Optionalをインポートするときは、java.util の Optional をインポートする。

これで、プレイリスト名がリンクで表示できるようになる。

プレイリスト名のリンクをクリックすると、まだテンプレートを作ってないのでエラーになる。

/playlist で表示するためのテンプレートを用意する。

src/main/resources の templates に playlist.html を作成する。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>プレイリスト</title>
</head>
<body>

<h1 th:text="${playlist.name}"></h1>

</body>
</html>

プレイリストに音楽を追加できるようにする。
とりあえず、音楽のリストを index.html からコピーしてきて、削除のリンクを追加に変更する。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>プレイリスト</title>
</head>
<body>

<h1 th:text="${playlist.name}"></h1>

<h3>このプレイリストに音楽を追加する</h3>

<h3>Musicリスト</h3>
<table>
	<tr>
		<th>ID</th>
		<th>タイトル</th>
		<th>アーティスト</th>
		<th>操作</th>
	</tr>
	<tr th:each="music : ${musics}">
		<td th:text="${music.id}"></td>
		<td th:text="${music.title}"></td>
		<td th:text="${music.artist}"></td>
		<td><a th:href="@{'/addtoplaylist/' + ${playlist.id} + '/' + ${music.id}}">追加</a></td>
	</tr>
</table>



</body>
</html>

IndexController で musics を playlist テンプレートに渡すようにする。

	@RequestMapping(value="/playlist/{id}", method=RequestMethod.GET)
	public ModelAndView playlist(ModelAndView mav,
			@PathVariable long id) {
		Optional<PlayList> r = playListRepository.findById(id);
		PlayList pl = r.get();
		mav.addObject("playlist", pl);
		List<Music> musics = musicRepository.findAll();
		mav.addObject("musics", musics);
		mav.setViewName("playlist");
		return mav;
	}

/addtoplaylist/{pid}/{mid} では、id=pid のプレイリストに id=mid の音楽を追加したい。
なので、以下のようにコードを書いてみる。

	@RequestMapping(value="/addtoplaylist/{pid}/{mid}", method=RequestMethod.GET)
	public ModelAndView addToPlaylist(ModelAndView mav,
			@PathVariable long pid,
			@PathVariable long mid) {
		Optional<PlayList> pr = playListRepository.findById(pid);
		PlayList pl = pr.get();
		Optional<Music> mr = musicRepository.findById(mid);
		Music m = mr.get();
		pl.addMusic(m);
		playListRepository.saveAndFlush(pl);
		return mav;
	}

pl.addMusic(m) のところでコンパイルエラーになっているので、クイックフィックスでメソッドを作成してエラーを消す。

package jp.kpc;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Entity
public class PlayList {
	@Id
	@GeneratedValue
	@Column
	@NotNull
	private long id;

	@Column
	@NotEmpty
	private String name;

	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void addMusic(Music m) {

	}
}

プレイリストを追加する addToPlaylist() では、/playlist/{pid} にリダイレクトする。

	@RequestMapping(value="/addtoplaylist/{pid}/{mid}", method=RequestMethod.GET)
	public ModelAndView addToPlaylist(ModelAndView mav,
			@PathVariable long pid,
			@PathVariable long mid) {
		Optional<PlayList> pr = playListRepository.findById(pid);
		PlayList pl = pr.get();
		Optional<Music> mr = musicRepository.findById(mid);
		Music m = mr.get();
		pl.addMusic(m);
		playListRepository.saveAndFlush(pl);
		return new ModelAndView("redirect:/playlist/" + pid);
	}

ひとつの PlayList に対して複数の Music を関連付ける。

PlayList

package jp.kpc;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Entity
public class PlayList {
	@Id
	@GeneratedValue
	@Column
	@NotNull
	private long id;

	@Column
	@NotEmpty
	private String name;

	@OneToMany
	private List<Music> musics;

	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void addMusic(Music m) {
		musics.add(m);
	}
	public List<Music> getMusics() {
		return musics;
	}
	public void setMusics(List<Music> musics) {
		this.musics = musics;
	}
}

Music

package jp.kpc;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Entity
public class Music {
	@Id
	@GeneratedValue
	@Column
	@NotNull
	private long id;

	@Column
	@NotEmpty
	private String title;

	@Column
	@NotEmpty
	private String artist;

	@ManyToOne
	private PlayList playList;

	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getArtist() {
		return artist;
	}
	public void setArtist(String artist) {
		this.artist = artist;
	}
	public PlayList getPlayList() {
		return playList;
	}
	public void setPlayList(PlayList playList) {
		this.playList = playList;
	}
}

テンプレート playlist に、プレイリストに登録済みの音楽リストを追加する。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>プレイリスト</title>
</head>
<body>

<h1 th:text="${playlist.name}"></h1>

<h3>このプレイリストに追加されている音楽</h3>
<table>
	<tr>
		<th>ID</th>
		<th>タイトル</th>
		<th>アーティスト</th>
	</tr>
	<tr th:each="music : ${playlist.musics}">
		<td th:text="${music.id}"></td>
		<td th:text="${music.title}"></td>
		<td th:text="${music.artist}"></td>
	</tr>
</table>


<h3>このプレイリストに音楽を追加する</h3>

<h3>Musicリスト</h3>
<table>
	<tr>
		<th>ID</th>
		<th>タイトル</th>
		<th>アーティスト</th>
		<th>操作</th>
	</tr>
	<tr th:each="music : ${musics}">
		<td th:text="${music.id}"></td>
		<td th:text="${music.title}"></td>
		<td th:text="${music.artist}"></td>
		<td><a th:href="@{'/addtoplaylist/' + ${playlist.id} + '/' + ${music.id}}">追加</a></td>
	</tr>
</table>



</body>
</html>

プレイリストから音楽を削除するためのリンクを追加する。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>プレイリスト</title>
</head>
<body>

<h1 th:text="${playlist.name}"></h1>

<h3>このプレイリストに追加されている音楽</h3>
<table>
	<tr>
		<th>ID</th>
		<th>タイトル</th>
		<th>アーティスト</th>
		<th>操作</th>
	</tr>
	<tr th:each="music : ${playlist.musics}">
		<td th:text="${music.id}"></td>
		<td th:text="${music.title}"></td>
		<td th:text="${music.artist}"></td>
		<td><a th:href="@{'/delete-music-from-playlist/' + ${playlist.id} + '/' + ${music.id}}">削除</a></td>
	</tr>
</table>


<h3>このプレイリストに音楽を追加する</h3>

<h3>Musicリスト</h3>
<table>
	<tr>
		<th>ID</th>
		<th>タイトル</th>
		<th>アーティスト</th>
		<th>操作</th>
	</tr>
	<tr th:each="music : ${musics}">
		<td th:text="${music.id}"></td>
		<td th:text="${music.title}"></td>
		<td th:text="${music.artist}"></td>
		<td><a th:href="@{'/addtoplaylist/' + ${playlist.id} + '/' + ${music.id}}">追加</a></td>
	</tr>
</table>



</body>
</html>

削除のリンクをクリックすると、Not Found のエラーになる。
コントローラでURLに対応したマッピングを作成する。

	@RequestMapping(value="/delete-music-from-playlist/{pid}/{mid}", method=RequestMethod.GET)
	public ModelAndView deleteFromPlaylist(ModelAndView mav,
			@PathVariable long pid,
			@PathVariable long mid) {
		Optional<PlayList> pr = playListRepository.findById(pid);
		PlayList pl = pr.get();
		Optional<Music> mr = musicRepository.findById(mid);
		Music m = mr.get();
		pl.deleteMusic(m);
		playListRepository.saveAndFlush(pl);
		return new ModelAndView("redirect:/playlist/" + pid);
	}

94行目のdeleteMusic()でコンパイルエラーが出ているので、クイックフィックスでメソッドを作成する。

PlayList

package jp.kpc;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Entity
public class PlayList {
	@Id
	@GeneratedValue
	@Column
	@NotNull
	private long id;

	@Column
	@NotEmpty
	private String name;

	@OneToMany
	private List<Music> musics;

	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void addMusic(Music m) {
		musics.add(m);
	}
	public void deleteMusic(Music m) {
		musics.remove(m);
	}
	public List<Music> getMusics() {
		return musics;
	}
	public void setMusics(List<Music> musics) {
		this.musics = musics;
	}
}

プレイリストの名前を変更できるようにする

playlist.html に入力フォームを追加する。

<h3>プレイリストの名前を変更する</h3>
<form action="/rename" method="post">
	<input type="hidden" name="id" th:value="${playlist.id}" />
	<input type="text" name="name" />
	<input type="submit" value="変更" />
</form>

コントローラに、名前を変更するためのマッピングを作成する。

	@RequestMapping(value="/rename", method=RequestMethod.POST)
	public ModelAndView rename(ModelAndView mav,
			@RequestParam("id") long id,
			@RequestParam("name") String name) {
		Optional<PlayList> r = playListRepository.findById(id);
		PlayList pl = r.get();
		pl.setName(name);
		playListRepository.saveAndFlush(pl);
		return new ModelAndView("redirect:/playlist/" + id);
	}

-SpringBoot

Copyright© 2021システム開発実習 , 2025 All Rights Reserved Powered by STINGER.