ホーム > Java > Spring Framework > Webアプリケーション > 登録機能作成(ユーザ登録)

登録機能作成(ユーザ登録)

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";

    }
}

リンク

コーポレートサイトにちょうどいいCMS、baserCMS