管理者のユースケースでは,メンバーの登録(UC02),取得(UC01),削除(UC03)を行う. よって,下記の順番で実装していく
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Member {
@Id
String mid; //メンバーID
String name; //氏名
}@Repository
public interface MemberRepository extends CrudRepository<Member, String>{
List<Member> findAll();
}Optional<Member> findById(String mid); //null安全な1件取得 (R) Iterable<Member> findAll(); //全メンバー取得 (R) Member save(Member member); //メンバー保存・更新 (C, U) void deleteById(String mid); //メンバー削除 (D) void deleteAll(); //メンバー全権削除 (D) boolean existById(String mid); //存在チェック Long count(); //登録件数
@Data
public class MemberForm {
String mid; //メンバーID.
String name; //名前
public Member toEntity() {
Member m = new Member(mid, name);
return m;
}
}public class ToDoAppException extends RuntimeException{
public static final int NO_SUCH_MEMBER_EXISTS = 101;
public static final int MEMBER_ALREADY_EXISTS = 102;
public static final int INVALID_MEMBER_INFO = 103;
public static final int INVALID_MEMBER_OPERATION = 104;
public static final int NO_SUCH_TODO_EXISTS = 201;
public static final int INVALID_TODO_INFO = 202;
public static final int INVALID_TODO_OPERATION = 203;
int code;
public ToDoAppException(int code, String message) {
super(message);
this.code = code;
}
public ToDoAppException(int code, String message, Exception cause) {
super(message, cause);
this.code = code;
}
public int getCode() {
return code;
}
}@Service
public class MemberService {
@Autowired
MemberRepository mRepo;
/**
* メンバーを作成する (C)
* @param form
* @return
*/
public Member createMember(MemberForm form) {
//IDの重複チェック
String mid = form.getMid();
if (mRepo.existsById(mid)) {
throw new ToDoAppException(ToDoAppException.MEMBER_ALREADY_EXISTS, mid + ": Member already exists");
}
Member m = form.toEntity();
return mRepo.save(m);
}
/**
* メンバーを取得する (R)
* @param mid
* @return
*/
public Member getMember(String mid) {
Member m = mRepo.findById(mid).orElseThrow(
() -> new ToDoAppException(ToDoAppException.NO_SUCH_MEMBER_EXISTS, mid + ": No such member exists"));
return m;
}
/**
* 全メンバーを取得する (R)
* @return
*/
public List<Member> getAllMembers() {
return mRepo.findAll();
}
/**
* メンバーを削除する (D)
*/
public void deleteMember(String mid) {
Member m = getMember(mid);
mRepo.delete(m);
}
}@Controller
@RequestMapping("/admin")
public class MemberController {
@Autowired
MemberService mService;
/**
* 管理者用・ユーザ登録ページ HTTP-GET /admin/register
* @param model
* @return
*/
@GetMapping("/register")
String showUserForm(Model model) {
List<Member> members = mService.getAllMembers();
model.addAttribute("members", members);
MemberForm form = new MemberForm();
model.addAttribute("MemberForm", form);
return "register";
}
/**
* 管理者用・ユーザ登録確認ページを表示 HTTP-POST /admin/check
* @param form
* @param model
* @return
*/
@PostMapping("/check")
String checkUserForm(@ModelAttribute(name = "MemberForm") MemberForm form, Model model) {
model.addAttribute("MemberForm", form);
return "check";
}
/**
* 管理者用・ユーザ登録処理 -> 完了ページ HTTP-POST /admin/register
* @param form
* @param model
* @return
*/
@PostMapping("/register")
String createUser(@ModelAttribute(name = "MemberForm") MemberForm form, Model model) {
Member m = mService.createMember(form);
model.addAttribute("MemberForm", m);
return "registered";
}
/**
* 管理者用・ユーザ削除処理 HTTP-GET /admin/delete/{mid}
* @param mid
* @param model
* @return
*/
@GetMapping("/delete/{mid}")
String deleteUser(@PathVariable String mid, Model model) {
mService.deleteMember(mid);
return showUserForm(model);
}
}<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>管理者画面</title>
</head>
<body>
<h1>管理者画面</h1>
<h2>メンバー新規登録</h2>
<p> メンバーIDと氏名を入力して,「確認する」を押してください.</p>
<ul>
<li>メンバーIDには,アルファベット小文字,数字,ハイフン,アンダーバーのみ使用できます</li>
</ul>
<form role="form" th:action="@{/admin/check}" th:object="${MemberForm}" method="post">
<table>
<tr>
<td><label>メンバーID: </label></td>
<td><input type="text" required th:field="*{mid}" /></td>
</tr>
<tr>
<td><label>氏名: </label></td>
<td><input type="text" required th:field="*{name}" /></td>
</tr>
</table>
<p><input type="submit" value="確認する" /></p>
</form>
<h2>登録済みメンバー</h2>
<table border="1">
<tr>
<th>メンバーID</th>
<th>氏名</th>
<th>コマンド</th>
</tr>
<tr th:each="m: ${members}">
<td>[[${m.mid}]]</td>
<td>[[${m.name}]]</td>
<td><a th:href=@{/admin/delete/{m}(m=${m.mid})}>削除</a></td>
</tr>
</table>
</body>
</html><!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登録確認</title>
</head>
<body>
<h1>登録確認</h1>
<p>
以下の情報でメンバーを登録します.よろしければ登録を押してください.
</p>
<form role="form" th:action="@{/admin/register}" th:object="${MemberForm}" method="post">
<p>
<label>メンバーID: </label>
[[*{mid}]]
</p>
<p>
<label>氏名: </label>
[[*{name}]]
</p>
<p>
<input type="button" value="戻る" onclick="history.back()" />
<input type="submit" value="登録する" />
</p>
<input type="hidden" th:field="*{mid}" />
<input type="hidden" th:field="*{name}" />
</form>
</body>
</html><!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登録完了</title>
</head>
<body>
<h1>登録完了</h1>
<p>
メンバー登録を完了しました.
</p>
<div th:object="${MemberForm}">
<p>
<label>メンバーID: </label>
[[*{mid}]]
</p>
<p>
<label>氏名: </label>
[[*{name}]]
</p>
<p>
<a th:href=@{/admin/register}>続けて登録する</a><br />
<a th:href=@{/}>初めに戻る</a>
</p>
</div>
</body>
</html>