登録機能作成(ユーザ登録)
PostgreSQLで作成したDBとSpring Data JDBCを使用する。
1. テーブル作成
- ユーザとロールを登録するテーブルを作成する。
- 今回は以下のようなテーブルを作成する。主キー(id)は自動で設定される。
create table user_info ( id serial not null , username varchar(255) not null , password varchar(255) not null , enabled boolean not null , create_at timestamp , update_at timestamp , primary key (id) , unique (username) );create table user_role( id serial not null , user_id integer not null , role varchar(256) not null , create_at timestamp , update_at timestamp , primary key (id) , unique (user_id, role) );
2. Entityクラス
user_info、user_roleテーブルに対応するEntityクラスを作成する。
- カラムに対応したフィールドを設定
- 主キーには@Idを指定
com/ziqoo/demo/dao/table/entity/UserInfo.java
@AllArgsConstructor
@NoArgsConstructor
@Data
@Table
public class UserInfo {
@Id
private Integer id;
private String username;
private String password;
private boolean enabled;
private LocalDateTime createAt;
private LocalDateTime updateAt;
}
/demo/src/main/java/com/ziqoo/demo/dao/table/entity/UserRole.java
@AllArgsConstructor
@NoArgsConstructor
@Data
@Table
public class UserRole {
@Id
private Integer id;
private Integer userId;
private String role;
private LocalDateTime createAt;
private LocalDateTime updateAt;
}
3. Repositoryクラス
user_info、user_roleテーブルをアクセスするインターフェースを作成 CrudRepositoryを継承するだけで 基本的なテーブルアクセスが可能
/demo/src/main/java/com/ziqoo/demo/dao/table/repository/UserInfoRepository.java
public interface UserInfoRepository extends CrudRepository<UserInfo, Integer> {
}
/demo/src/main/java/com/ziqoo/demo/dao/table/repository/UserRoleRepository.java
public interface UserRoleRepository extends CrudRepository<UserRole, Integer> {
}
4. Roleをenumとして作成
今回はRoleをenumとして作成する。
/demo/src/main/java/com/ziqoo/demo/security/Role.java
package com.ziqoo.demo.security;
public enum Role {
Admin, User
}
5. Serviceクラス
登録を行うServiceクラスを作成
/demo/src/main/java/com/ziqoo/demo/service/account/AccountService.java
package com.ziqoo.demo.service.account;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import com.ziqoo.demo.dao.table.entity.UserInfo;
import com.ziqoo.demo.dao.table.entity.UserRole;
import com.ziqoo.demo.dao.table.repository.UserInfoRepository;
import com.ziqoo.demo.dao.table.repository.UserRoleRepository;
import com.ziqoo.demo.security.Role;
@Service
public class AccountService {
private UserInfoRepository userInfoRepository;
private UserRoleRepository userRoleRepository;
private PasswordEncoder passwordEncoder;
@Autowired
public AccountService(UserInfoRepository userInfoRepository, UserRoleRepository userRoleRepository,
PasswordEncoder passwordEncoder) {
this.userInfoRepository = userInfoRepository;
this.userRoleRepository = userRoleRepository;
this.passwordEncoder = passwordEncoder;
}
/**
* ユーザー登録.
* @param username
* @param password
* @param roleList
* @return
*/
@Transactional
public UserInfo registerAccount(String username, String password, List<Role> roleList) {
LocalDateTime now = LocalDateTime.now();
UserInfo user = new UserInfo();
user.setUsername(username);
user.setPassword(passwordEncoder.encode(password));
user.setEnabled(true);
user.setCreateAt(now);
user.setUpdateAt(now);
user = userInfoRepository.save(user);
Integer userId = user.getId();
roleList.forEach(role -> {
UserRole userRole = new UserRole();
userRole.setUserId(userId);
userRole.setRole(role.name());
userRole.setCreateAt(now);
userRole.setUpdateAt(now);
userRoleRepository.save(userRole);
});
return user;
}
}
6. Formクラス
画面とController間でデータを受け渡しするFormクラスを作成する
/demo/src/main/java/com/ziqoo/demo/web/form/account/AccountForm.java
package com.ziqoo.demo.web.form.account;
import java.io.Serializable;
import java.util.List;
import com.ziqoo.demo.security.Role;
import lombok.Data;
@Data
public class AccountForm implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private String password;
private List<Role> roleList;
}
7. 登録画面
登録画面を作成する。テンプレートエンジンとしてThymeleafを使用する。
/demo/src/main/resources/templates/account/registration.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" th:href="@{/css/common.css}">
<title>Account registration</title>
</head>
<body>
<div class="header">
<h2>ユーザー登録</h2>
</div>
<div id="message" th:if="${message}">
<span th:text="${message}"></span>
</div>
<div id="content">
<form th:action="@{/account/register}" th:object="${accountForm}"
method="post">
<table>
<tr>
<td><label for="username">ユーザ名</label></td>
<td><input type="text" th:field="*{username}"></td>
</tr>
<tr>
<td><label for="password">パスワード</label></td>
<td><input type="password" th:field="*{password}"></td>
</tr>
<tr>
<td><label>Role</label></td>
<td>
<div th:each="item : ${roles}">
<input type="checkbox" th:value="${item}" th:field="*{roleList}" />
<label th:for="${#ids.prev('roleList')}" th:text="${item}"></label>
</div>
</td>
</tr>
</table>
<button>登録</button>
</form>
</div>
</body>
</html>
8. Controllerクラス
Controllerクラスを作成する。
GETで画面表示、POSTで登録処理を行う。
/demo/src/main/java/com/ziqoo/demo/web/controller/account/AccountController.java
package com.ziqoo.demo.web.controller.account;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.ziqoo.demo.dao.table.entity.UserInfo;
import com.ziqoo.demo.security.Role;
import com.ziqoo.demo.service.account.AccountService;
import com.ziqoo.demo.web.form.account.AccountForm;
@Controller
public class AccountController {
private static final Logger logger = LoggerFactory.getLogger(AccountController.class);
@Autowired
private AccountService accountService;
@GetMapping("/account/register")
public String registrationPage(@ModelAttribute("accountForm") AccountForm form, Model model) {
model.addAttribute("roles", Role.values());
return "account/registration";
}
@PostMapping("/account/register")
public String register(AccountForm accountForm, RedirectAttributes ra) {
UserInfo user = accountService.registerAccount(accountForm.getUsername(), accountForm.getPassword(), accountForm.getRoleList());
logger.debug("ユーザを登録しました。{}:{}", user.getId(), user.getUsername());
String message = user.getUsername() + "を登録しました。";
ra.addFlashAttribute("message", message);
return "redirect:/account/register";
}
}

