概要
VSCodeでSpring Bootアプリケーション作成と
PostgreSQLに登録されているユーザでログインを行う
全体像
前提知識
SpringBoot, Thymeleaf を利用したアプリケーションの基本的な理解
環境情報
- Java SE 17
- PostgreSQL 16.2
拡張機能
拡張機能名 | 備考 |
---|---|
Java Extension Pack | Java開発のための機能が含まれた一連のパッケージ |
Spring Boot Extension Pack | Spring Bootアプリケーション開発のための機能が含まれた一連のパッケージ |
Maven for Java | Mavenプロジェクトの管理用 |
Spring Boot アプリケーションの作成
-
プロジェクトの選択内容
選択項目 選択内容 Spring Boot Version 3.2.3 Project Language Java パッケージ名 com.example (任意のパッケージ名) プロジェクト名 demo (任意のプロジェクト名) Packaging Type jar Java Version 17
-
依存関係の追加内容
下記依存関係を選択したらEnterを押し、任意のフォルダに保存するdependencies 備考 Spring Web 自己完結型の HTTP サーバーを作成できる Spring Boot Devtools 再起動なしにソースコードの修正を反映させることができる (無くても問題ないがあると便利) Thymeleaf Javaのウェブ開発用テンプレートエンジン JDBC API JavaとDBを接続するためのAPI PostgreSQL Driver PostgreSQLと通信するためのドライバー
ここで一旦起動したいところですが、DB接続エラーが発生してしまうため
PostgreSQLとの接続情報を追加します
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
PostgreSQLとの連携
-
アプリケーションプロファイルの設定
src/main/resources配下の「application.properties」を「application.yml」にリネームし、以下の内容を記載appliation.ymlspring: datasource: url: jdbc:postgresql://localhost:5432/test # 接続先URL username: postgres # ユーザー名 password: postgres # パスワード
-
簡易的なhtmlの作成
ログインページ「src/main/resources/tmplates/login.html」
ログイン成功ページ「src/main/resources/tmplates/home.html」login.html<!DOCTYPE html> <html lang="ja" xmlns:th="https://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ログインページ</title> </head> <body> <h1>ログイン</h1> <div style="color: red;" th:text="${message}"></div> <form action="/login" method="post"> <div> <label for="username">ユーザ名</label> <input type="text" id="name" name="name" th:value="${name}"> </div> <div> <label for="password">パスワード</label> <input type="password" id="password" name="password"> </div> <button type="submit">ログイン</button> </form> </body> </html>
home.html<!DOCTYPE html> <html lang="ja" xmlns:th="https://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ログインページ</title> </head> <body> <h1>ログイン成功</h1> </body> </html>
-
usersテーブルの作成
本来であればパスワードは暗号化して格納するべきだが、今回は暗号化処理未実装カラム名 値 name admin password admin sql.txt-- usersテーブルがあれば削除 DROP TABLE IF EXISTS users CASCADE; -- usersテーブル作成 CREATE TABLE users( name varchar(20) PRIMARY KEY , password varchar(20) NOT NULL ); -- データ挿入 INSERT INTO users(name, password) VALUES('admin', 'admin');
-
Repositoryの作成
DBからの情報を取得するためのRepositoryクラスを作成する
「 src/main/java/com/example/demo/repository/UserRepository.java 」- 依存関係で追加したJdbcTemplate(NamedParameterJdbcTemplate)を利用
- ユーザーが見つかればユーザー情報を、見つからなければ空を返す
UserRepository.javapackage com.example.demo.repository; //〜〜〜〜import文は省略〜〜〜〜〜 @Repository public class UserRepository { @Autowired private NamedParameterJdbcTemplate jdbcTemplate; // RowMapperの実装 private static final RowMapper<User> ROW_MAPPER = (rs, i) -> { String name = rs.getString("name"); String password = rs.getString("password"); return new User(name, password); }; /** * ユーザー名とパスワードからユーザーを取得する. * * @param name ユーザー名 * @param password パスワード * @return ユーザー情報、存在しない場合は空のOptional */ public Optional<User> findByUser(String name, String password) { SqlParameterSource param = new MapSqlParameterSource().addValue("name", name).addValue("password", password); String sql = "SELECT * FROM users WHERE name = :name AND password = :password"; List<User> userList = jdbcTemplate.query(sql, param, ROW_MAPPER); return userList.stream().findFirst(); } }
-
Domainの作成
User.javapackage com.example.demo.domain; public record User(String name, String password) {}
-
Serviceの作成
UserService.javapackage com.example.demo.service; //〜〜〜〜import文は省略〜〜〜〜〜 @Service public class UserService { @Autowired private UserRepository userRepository; public Optional<User> findByUser(String name, String password) { Optional<User> user = userRepository.findByUser(name, password); System.out.println(user); return user; } }
-
Controllerの作成
LoginController.javapackage com.example.demo.controller; //〜〜〜〜import文は省略〜〜〜〜〜 @Controller @RequestMapping("") public class LoginController { @Autowired private UserService userService; @Autowired private HttpSession session; @GetMapping("") public String login() { return "/login"; } @GetMapping("/login") public String loginPage(Model model) { return "/login"; } /** * ログイン処理を行う * * @param name ユーザー名 * @param password パスワード * @param model モデル * @return ログイン成功時は/home、失敗時は/loginに遷移 */ @PostMapping("/login") public String login(String name, String password, Model model) { return userService.findByUser(name, password) .map(user -> { session.setAttribute("user", user); return "/home"; }) .orElseGet(() -> { model.addAttribute("name", name); model.addAttribute("message", "ユーザー名またはパスワードが違います"); return "/login"; }); } @GetMapping("/home") public String home() { if (session.getAttribute("user") == null) { return "redirect:/login"; } return "/home"; } }
参考資料
NamedParameterJdbcTemplate
SpringBootのO/Rマッパー
streamインターフェース リファレンス
Optional リファレンス
Optional
recordクラス