0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SpringBootでとりあえず業務アプリを自作してみた ~TOP・ユーザ検索編~

Posted at

前回までで、作成したアプリをWEBアプリとして公開しました。

その後、少し機能を追加してみたのでまとめます。

トップ画面

ユーザの登録機能を作成しました。
最初はログイン画面に設置していましたが
ログイン後の画面に設置しなおしました。
image.png

トップページにはまだ何も置いていません。
お知らせ機能とか、カレンダーとか置きたいなと思っていますが
これから徐々に機能を増やしていきたいなと思っています。

前回までの記事でも記載しましたがログイン機能はSpringSecurityを使用しました。

手を動かしてコーディングをするのが数年ぶりなのと
SpringBootでアプリを作成するのが初めてなので
色々探り探りで躓きながらですが作成を進めています。

右上の「山田 太郎」はcontrollerから受け取ったログインユーザの名前が出るようにしています。

以下の記事の後ろのほうに記載したcssが適用されない件ですが解決しました。

当初は以下のような階層にしていたのですが

└── src
   └── main
     ├── java
     └── resources
       └── static
        └── templates
          └── index.html // cssを適用させたいhtml
          └── css
            └── style.html

このようにしたら読み込めるようになりました。

└── src
   └── main
     ├── java
     └── resources
       └── static
        ├── templates
        | └── index.html // cssを適用させたいhtml
        └── css
            └── style.html

Thymeleafを使用しているので、記述方式がThymeleaf式です。
ちなみに
th:src … HTML 文書中に埋め込む画像やスクリプトなどのリソース
th:href … HTML 文書にリンクするリソース
という区別だそうです。

画面側はあまりやってこなかったので勉強になりました。

同じように右上のアイコン画像も読み込めたので
ログアウト用のアイコンとして設置しています。

index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
	<meta charset="UTF-8">
	<link th:href="@{/css/style.css}" rel="stylesheet">
	<script th:src="@{https://code.jquery.com/jquery-3.4.1.min.js}"></script>
</head>

<body class="in-body">

<!-- 以下略 -->

ヘッダー部分を共通化したかったのですが、こちらはうまくいきませんでした。
どうにもHTMLがうまく読み込まれない...
またしばらくしたらトライしたいです。

ユーザ検索画面

登録したユーザ情報が検索できる画面を作成しました。
メニューの「ユーザ管理」から遷移する先がこちらです。
image.png

全件検索が以下
image.png

テーブルはjQuaryで作成するか迷いましたが
Thymeleafの機能で作成しました。便利です。

ソースコードはこんな感じ。

UserController.java
/**
	 * ユーザ検索画面の処理(GET)
	 * @return
	 */
	@GetMapping("/userSearch")
	public ModelAndView userSearchForm(@ModelAttribute UserSearchDto userSearchDto) {
		// 画面に返却するオブジェクトを生成
		ModelAndView mav = new ModelAndView();
		// ログイン情報を取得
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		UserPrincipal userInfo = (UserPrincipal) authentication.getPrincipal();

		if (userInfo != null) {
			// ユーザ情報が取得できた場合は名前をセット
			mav.addObject("name", userInfo.getUser().getLastName() + " " + userInfo.getUser().getFirstName());
		}

		if (userSearchDto.getViewType() == null) {
			// 初期表示処理
			mav.addObject("userSearchDto", new UserSearchDto());
			mav.setViewName("userSearch");
			return mav;
		}

		// 検索実行時処理
		List<User> users = null;

		if (userSearchDto.getUserId().isBlank() &&
				userSearchDto.getFirstName().isBlank() &&
				userSearchDto.getFirstNameKana().isBlank() &&
				userSearchDto.getLastName().isBlank() &&
				userSearchDto.getLastNameKana().isBlank() &&
				userSearchDto.getRoleAdmin() == 0 &&
				userSearchDto.getRoleEmployee() == 0 &&
				userSearchDto.getRoleContract() == 0 &&
				userSearchDto.getValid() == 0) {
			// 全件検索
			users = userService.findAll();
		} else {
			// 部分検索
			users = userDaoImpl.search(userSearchDto);
		}

		mav.addObject("userSearchDto", new UserSearchDto()); // 次の検索実行用の入れ物

		if (users.isEmpty()) {
			// ユーザ情報が1件も取得できなかった場合
			mav.addObject("msg", CommonVariable.MSG_02);
		} else {
			mav.addObject("users", users);
		}

		mav.setViewName("userSearch");
		return mav;
	}

userSearch.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
	<meta charset="UTF-8">
	<link th:href="@{/css/style.css}" rel="stylesheet">
	<script th:src="@{https://code.jquery.com/jquery-3.4.1.min.js}"></script>
</head>

<body class="in-body">

	<!--ヘッダー共通部分(略) -->

	<main>
		<p class="view-title">ユーザ検索</p>
		<div class="search-form">
			<form th:action="@{/userSearch}" th:object="${userSearchDto}" method="get">
				<label class="search-label">ユーザID</label>
				<input type="text" id="userId" name="userId"><br>
				<label class="search-label">ユーザ名</label>
				<input type="text" id="lastName" name="lastName" placeholder="姓">
				<input type="text" id="firstName" name="firstName" placeholder="名"><br>
				<label class="search-label">ユーザ名(カナ)</label>
				<input type="text" id="lastNameKana" name="lastNameKana" placeholder="セイ">
				<input type="text" id="firstNameKana" name="firstNameKana" placeholder="メイ"><br>
				<label for="email" class="search-label">メールアドレス</label>
				<input type="text" id="email" name="email"><br>
				<label class="search-label">権限</label>
				<input type="checkbox" name="roleAdmin" value="1" /><label>管理者</label>
				<input type="checkbox" name="roleEmployee" value="1" /><label>社員</label>
				<input type="checkbox" name="roleContract" value="1" /><label>契約社員</label><br>
				<label class="search-label">有効/無効</label>
				<input type="checkbox" id="valid" name="valid" value="1" /><label for="valid">無効を含む</label><br>
				<input type="hidden" name="viewType" value="search" />
				<button class="submit" type="submit" value="Submit">検索</button>
				<button class="reset" type="reset" value="Reset">リセット</button>
				<button class="register" type="register" value="Register"><a th:href="@{/userRegister}">新規登録</a></button>
			</form>
		</div>
		<a class="search-msg" th:if="${msg}" th:text="${msg}"></a>
		<table>
			<tr th:if="${users}">
				<th>ユーザID</th>
				<th id="fix"></th>
				<th id="fix"></th>
				<th id="fix">メールアドレス</th>
				<th id="fix">権限</th>
				<th id="fix">有効/無効</th>
				<th></th>
			</tr>
			<tr class="data-table" th:each="item: ${users}">
				<td class="fix" th:text="${item.userId}"></td>
				<td class="fix" th:text="${item.lastName}"></td>
				<td class="fix" th:text="${item.firstName}"></td>
				<td class="fix" th:text="${item.email}"></td>
				<td class="fix" th:if="${item.roleCode} eq 0">システム管理者</td>
				<td class="fix" th:if="${item.roleCode} eq 1">管理者</td>
				<td class="fix" th:if="${item.roleCode} eq 2">社員</td>
				<td class="fix" th:if="${item.roleCode} eq 3">契約社員</td>
				<td class="fix" th:if="${item.validFlag} eq true">有効</td>
				<td class="fix" th:if="${item.validFlag} eq false">無効</td>
				<td>
					<a th:href="@{/userRef(userId=${item.userId})}"><img class="edit" th:src="@{/img/edit.png}" height="20px"></a>
				</td>
			</tr>
		</table>
	</main>
	<footer></footer>
</body>
<script th:src="@{/js/common.js}"></script>
</html>

th:each="item: ${users}"

これが便利です。
usersにはControllerから渡されたUserのリストが格納されており
これが存在した場合はリストの数だけ次のコードの生成を行ってくれます。

ログイン情報の取得方法についてや初期表示の判定方法は
他にもっと効率的な処理の仕方があるような気がしますが
技術不足があるので勉強しつつでアップデートしていけたらなと思います。

HTMLは基本的にノリで書いているので
フロントエンジニアから見るとダメダメかもしれません。
idとclassの使い分けとか、divタグ aタグ pタグの使い分けとかあんまりよくわかってません...
classはグループ名でidは項目単位の名前ってくらいの認識。

検索ボタンからは検索画面に、
新規登録ボタンからは新規登録画面に
テーブルの行の一番右のアイコンからは編集画面に遷移します。
リセットの処理はjQuaryで実装したいですがまだできていません。

組みながら最善を模索していますので
javaでもhtmlでも、こんな方法があるよ!こうしたらもっといいよ!
など、アドバイス等あればコメントいただけるとと思います。

思ったより長くなってしまったので今回は一旦ここまで、
次回、検索処理の詳細と、新規登録・編集の処理について書いていきたいと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?