Java JSP,Servletを使ったポートフォリオ制作



#はじめに
こんにちは！ 閲覧頂きありがとうございます。

今回Java、JSP、Servletを使って、ポートフォリオを制作しました。
制作していく中で学んだこと、苦労したこと、ポートフォリオについての説明も兼ねて記事にしました。

まだ実装できていない機能や不完全な箇所もありますが、説明させて頂きます。
#概要
製造業における工数を管理するシステム

概要は以下の二点です。
1.工数管理者の負担を軽減
2.具体的な工数の可視化

工数管理システムを英語訳で、
Product Cost Management System
それぞれの頭文字を取って、"PCMS"　というシステムを開発しました。

GitHub URL:https://github.com/nakamurakihiro/PCMS
![PCMS-work_report.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/9322173f-e92a-c5ef-13c1-e41a89d10228.gif)

#制作背景
私は高校卒業後から製造業で働いており、日々の業務の中で工数短縮を徹底してきました。
しかし、工数を管理する側の業務を見てきて以下のような問題点があることに気づきました。

・作業内容を日報用紙に記入し、管理者がPCで1つ1つ手入力している。
・管理者側での工数管理に時間がかかっている。

という観点から、**もっと効率よく工数を管理し、管理者側の負担を減らしたい** といった思いで、このシステムを開発しました。

#使用技術
・jdk-16.0.2
・Servlet
・JSP
・HTML,CSS
・MySQL 8.0.26
・Tomcat 9.0.52

Javaの仕組みや理解を深めるために、フレームワークは使わずに実装しました。
#機能一覧
〇基本機能
・ログイン,ログアウト機能
・社員・管理者新規登録機能
・社員・管理者パスワード変更機能　
・社員・管理者ゲストログイン機能　

〇社員機能
・工数記録機能
・マイページ編集機能
・工数記録一覧表示機能

〇管理者機能
・登録社員情報と工数記録の一覧表示機能
・工数記録編集、削除機能
・各社員毎の工数記録一覧表示機能
・各部署毎の工数合計時間表示機能
・各機械毎の工数合計時間表示機能

## 使用画面イメージ

ログイン画面
![ログイン画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/bba0bf42-5bf5-5ee7-cd95-1615ade51a6c.png)

新規登録画面
![新規登録画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/4cf403f7-7c2f-c4fd-b25a-44cedd4c3ac5.png)

工数記録画面
![工数記録画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/8c034fc5-cd4c-40c0-622a-9c2d4c03e56a.png)

マイページ
![マイページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/fdb4241e-f52f-f13b-f7e2-e3bbb3ad6f27.png)

パスワード変更画面
![パスワード変更画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/7e11980c-6eab-19e7-7473-deec81f0bfb6.png)


管理者メニュー
![管理者メニュー画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/16c5d675-389f-6f4f-d954-e522777c2dae.png)

工数記録一覧
![工数記録一覧画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/85969eef-3276-6ee7-3456-8ad08b024fdf.png)

社員一覧
![社員一覧画面1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/6b98ddcf-c27e-af33-2ce5-a73359aa8a33.png)

機械工数画面
![機械工数画面1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/28600fdd-f779-a8b6-7584-630675877e20.png)


#DB設計
**各テーブルについて**
![テーブル情報](https://user-images.githubusercontent.com/75915650/131236233-67969f7e-b598-4729-8748-76a0fbede73b.png)

**各テーブル詳細**

![employee_report_table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/fcea7630-bfcf-4dd2-28f2-51bc74a5d951.png)
![machine_work_table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/37f8ecf9-9cbf-9d0a-1016-c5c234d25238.png)
![department_admin_table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/7c32b128-ac4c-360f-e0fb-1b751fe83ff2.png)



#工夫したこと
**フレームワークを使わずに開発**
Java自体の言語理解を深めるためにフレームワークを使わずに開発しました。
フレームワークを使えば簡単に実装できた部分もあったかもしれませんが、私自身まずはしっかりと理解を深めていきたいと思ったので、言語だけ実装するということにこだわって開発しました。

**記録した工数合計時間を自動計算して表示**
管理者画面で、社員が記録した工数時間を部署や機械毎に自動計算し、工数合計時間を表示するようにしました。
![PCMS-machine_list.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/ab16ce9c-3651-949c-1eeb-c74c29eea032.gif)


#苦労したこと
**JSP DB登録データの表示**
JSP側にDBの登録データを表示させる実装に時間がかかり、かなり苦労しました。

理由としてはServletの仕組みをきちんと理解できておらず、JSPとServletの連携を上手く活用できていなかったのが原因でした。

**パスワード変更機能**
DB登録パスワード、現在パスワード、新しいパスワード、新しいパスワード（確認用）
この4つを設定した正規表現、nullチェックする機能の実装で、ソースコードが冗長になってしまいました。

冗長性を改善するために、オブジェクト指向に基づいてリファクタリングすることに時間がかかりました。

最終的には、拡張for文で実装することができました。

ソースコード一部抜粋↓

```Java:
         //セッションオブジェクトの生成
		HttpSession session = request.getSession();

    	//ログインした社員情報の取得
		Employee syain = (Employee)session.getAttribute("employee");

		//社員番号の取得
		int number = syain.getNumber();

		//社員パスワードの取得
		String employee_password = syain.getEmployee_Password();

		//パスワード変更画面から現在のパスワードを取得
		String currentPassword = request.getParameter("current_password");

		//パスワード変更画面から新しいパスワードを取得
		String newPassword = request.getParameter("new_password");

		//パスワード変更画面から確認用パスワードを取得
		String renewPassword = request.getParameter("renew_password");

		//パスワード検査準備
		CheckControlManager ccm = new CheckControlManager();

		//配列に検査対象パスワードを代入
		String[] password = {employee_password,currentPassword,newPassword,renewPassword};

		//null・未入力判定
		boolean nullEmptyJudge = true;

		//検査対象パスワードを順番に処理
		for(String target:password){

			//null・入力チェック
			nullEmptyJudge = ccm.nullEmpty(target);

			//falseなら処理を抜ける
			if(!nullEmptyJudge) {
				//エラー該当箇所を特定
				error_target = target;
				break;
			}
		}

		//employee_passwordでエラー
		if(error_target == employee_password) {
			RequestDispatcher disp = request.getRequestDispatcher("employee_password_error.jsp");
			disp.forward(request, response);
			return;
		}

		//currentPasswordでエラー
		if(error_target == currentPassword) {
			RequestDispatcher disp = request.getRequestDispatcher("current_password_error.jsp");
			disp.forward(request, response);
			return;
		}

		//newPasswordでエラー
		if(error_target == newPassword) {
			RequestDispatcher disp = request.getRequestDispatcher("new_password_error.jsp");
			disp.forward(request, response);
			return;
		}

		//renewPasswordでエラー
		if(error_target == renewPassword) {
			RequestDispatcher disp = request.getRequestDispatcher("renew_password_error.jsp");
			disp.forward(request, response);
			return;
		}
```

**工数合計時間の自動計算表示**
機械毎、部署毎に記録した工数記録を合計計算してJSP側で表示させるために、下記SQL文を使用しました。

```Java:
String sql = "update departments set department_hours = (select sum(work_time) + sum(over_time) + sum(holiday_work) from reports where department_code = ? and machine_name = ? group by machine_name) where department_code = ? and machine_name = ?";
```

このSQL文を使用して試してみましたが、どのように値を呼んでくるか、どう計算したらいいか、SQL自体の知識不足で機能の実装に苦労しました。

また同時にJavaだけでなく、SQLは改めてきちんと理解しないといけない内容だと気づき、SQLの知識向上の必要性を学びました。

#制作する上で意識したこと
**画面デザインはシンプルに**
・現場作業員の中にはPCやスマホに不慣れな方がいらっしゃるので、実際に使用することを想定し、社員画面に情報は多く入れず、シンプルな画面デザインを心掛けました。

**ソースコードの可読性を意識する**
・変数名、メソッド名は、他者が見て用途が理解できるものにする。
・字下げを使って読みやすくする。
・Javadocコメントを記述して仕様書の作成
　変数名、クラス、メソッドの概要説明をJavadocコメントで記述
　仕様書を作成し、他者へ理解できるようにする。
![javadoc_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844098/ef2d21e6-7d66-2f85-d556-1c4123e2d390.png)


#今後の課題・改善点

**各画面デザイン変更**
画面の見やすさと利便性を向上させるために、JavaScriptの学習も行い、画面デザインの修正を図る。

**グラフや図を使った工数記録の可視化**
管理者画面において、工数記録の合計時間を表示できるようにしていますが、
グラフや図などを使って、さらに工数時間を見やすくする。

**管理者パスワードの改善**
管理者権限付与条件として、社員としてログイン後、現状設定している管理者パスワードと同じパスワードを入力し、一致していれば管理者権限を付与するよう実装しています。

しかし、上記を踏まえた上で以下の問題点があります。

・管理者パスワードを知る術がシステム上にないこと。
（既に設定している管理者パスワードを他の管理者に口答で聞かないといけない）

・管理者パスワードを一人が変更してしまうと、他の管理者に変更を伝える術がない。
（口答のみ）

現状考えている解決策として、
1.管理者権限を取得する際には、個人のメールアドレスを入力し、メールアドレス宛に管理者パスワードを送信し、確認できるようにする。
2.管理者パスワードを変更する際は、登録している他の管理者にパスワード変更の旨をメールで送信する。

以上2点を実装し、管理者機能をさらに使いやすくしたいです。

#反省点
**DB設計**
テーブル名やカラム名を命名規則に従って作成していなかったことや外部キーの使い方などを理解しておらず、開発終盤でこの問題に気づきました…。

DB設計は、初期段階でもう少し深堀して学習するべき内容であることに加えて、
初期設計の重要性を身に染みて実感しました。

同じミスを繰り返さないように、今回の反省点を踏まえ今後に活かしていきます。

#今後やっていきたいこと
・社員、工数記録の検索機能
・画像投稿機能
・工数記録を選択して、選択した工数の合計時間と平均時間を計算、表示
・管理者からの工数記録に関するフィードバック機能
・管理者権限を取得する際のセキュリティ対策　など

#最後に
まだまだ実装したいことや修正したいことなど沢山ありますが、実際に制作してみて感じた事は、**継続することの大切さ**です。

制作していく中で、頭の中でイメージはできていても、コードを書いてそれを具現化することは想像以上に大変でした。
またエラーにハマり、全く進まなかった時期もありました。
しかし、日々の学習を継続してきたからこそ、改善策を見つけ、ポートフォリオとして形に残せたのかなと思います。
今後も技術力の向上を図るために、積極的に色々な技術を学んで、毎日の学習を継続していきます。

長くなりましたがここまで読んで頂き、ありがとうございました。
ご意見・ご質問等あれば、コメントで教えて頂けますと幸いです。