概要
本記事では、プログラミング初学者が初めてWebアプリを作成してみて詰まったことや困ったことなどをまとめました。今回は実装編です。
環境構築編もありますので、是非そちらも併せて読んでいただければと思います。
基本的には以下の記事で作成しているポモドーロタイマーと同じものを作成しています。
設計やコードなどはほぼほぼ一緒ですので詳細はそちらをご参照ください。
作成したアプリ画面
参考元の記事と少し違いますがcssの変更によるものだけで機能は同じです。
環境
- Windows10
- Eclipse 2021
- Java 11
- PostgreSQL14
作業してみて詰まったこと・困ったこと
Eclipseは使える!記事も読んだ!けどどこから手を付けたらいいんだろう…
と困ってしまったので参考元の記事で当たり前のように使っているデータベースやライブラリの準備からコードを書いて実装するまで、調べながらどうにかしたことを書いていきます。今回は実装時のあれこれについてです。
実装編
インポートもできてあとはコードを元記事の通りに作成したら完成間近です。
と思いきや、ただ同じものを記述するだけではうまく実行できず、詰まってしまいました。
うまく実行できなかった箇所やそれに伴って変更した点など書いていきます。
serviceパッケージにエラーがでる
エラーが出るのは以下の2カ所です。
@Transactional(rollbackOn = Exception.class)
public TasksEntity registerTask(TaskForm taskForm) throws RuntimeException {
Timestamp currenttime = tasksRep.getCurrentTime();
@Transactional(rollbackOn = Exception.class)
public void endTask(TaskForm taskForm) throws RuntimeException {
Timestamp currenttime = tasksRep.getCurrentTime();
どちらのクラスも rollbackOn
の部分に赤い波線が引かれエラーが出ていました。
解決策
>> @Transactional (rollbackFor = Exception.class)
に書き換える
調べてみると、@ Transactionalのアノテーションですべての例外が発生した場合にロールバックさせることができるらしく、その際の記述は @Transactional (rollbackFor = Exception.class)
と書くことができるようです。
アプリを実行し直したらポート番号が被る
おそらく私ほどの初心者でない限りこの問題には困らないと思うのですが…
変更後の実行結果を確認したくて再度プロジェクトを実行しようとするたびにポート番号が使われているといった内容がコンソールに表示されていて困りました(いちいちポート番号を変えてました)。
解決策
>> アプリを停止させてから再起動する
コンソールで■のボタンでアプリケーションを停止させてから再度実行することでポート番号が被ることなく実行できるようになりました。
後から気づいたのですが、cssやjsファイルを変更したらページをリロードするだけで事足りました。
わざわざアプリを再起動する必要もなかったようです!!
Webページが見つからない
全てのコードを書き終えてブラウザにURLを打ち込むと「Webページが見つかりません」と出てきてしまいました。
解決策
>> きちんとWebページが表示されるサンプルアプリを作成し、そこに肉付けしていく形で実装してみる
まずはHelloWorldとだけ表示されるものを作り、cssを追加したりjsファイルを追加したりして正常に動作することを確かめながら進めました。
ライブラリをプロジェクトにインポートしたりデータベースに接続しても問題なく動作することを確認しながら追加していくとControllerクラスを追加した時点でうまくいかなくなることがわかり、結果的に原因を突き止めることができました。
探してみると他にも少し原因があったようなので以下に細かい原因と解決策を書いていきます。
原因1:Controllerクラスの記述の仕方
Controllerの箇所にブレークポイントを設定しデバックしてみると処理が止まってくれないのでおそらくControllerクラスに処理が届いてないかもしれないという事がわかりました。
解決策
>> @ GetMappingを@ RequestMappingに書き換える
@ RequestMappingを使っていた簡単なサンプルアプリではWebページが表示できていたので、そこが原因かと思い以下の通りに書き直した結果Webページが表示されるようになりました。
(@ GetMappingでうまく動作しなかった細かい理由はわかっていません…)
(package文、import文は略)
・・・
/**
* 初期表示処理
*
* @param mav ModelAndView
* @return 初期表示情報
*/
@RequestMapping("/index")
public ModelAndView init(ModelAndView mav){
TaskForm taskForm = new TaskForm();
mav.addObject("taskForm", taskForm);
mav.setViewName("index.html");
return mav;
}
・・・
原因2:Eclipseの内部Webブラウザ
色々コードを調べた結果view-index.jsのどこかに原因があるとわかりました。さらに細かく見てみると$ajax~
の部分だけコメントアウトするとうまく実行できるので、そこに問題があるのではと思ったらEclipse側に要因があったようです。
解決策
chromeで起動したら問題なく動作しました。どうやらEclipseの内部Webブラウザでは動かず、chromeなどのブラウザなら動作するみたいです。
タイマーのボタンを押しても何も起こらない
ボタンが押された時に呼び出されるメソッドの記述は何度確認しても間違っていなさそう…なのにボタン押してもタイマーが動かなくて困りました。
解決策
>> jsファイルとHTMLを少し書き換える
HTML側でonclick="startClick"
という記述(startボタン押されたらstartClickメソッド呼び出すやつ)を足して、jsファイル側で呼び出されるメソッド(startClickメソッド)を新しく書いてみたら無事動作しました。
※stopボタンも同様に変更
<div class="col-md-4 "><button id="startButton" type="button" class="btn btn-block btn-success" onclick="startClick()" >Start</button></div>
<div class="col-md-4 "><button id="stopButton" type="button" class="btn btn-block btn-danger"onclick="stopClick()" >Stop</button></div>
・・・
/*--------------------------------
* タスクを開始
--------------------------------*/
function startClick(){
alert("タスクを開始")
startbtnOn();
$("#timerView").countdowntimer("stop", "start");
var form = $('#TaskForm').serializeArray();
var formdata = {};
jQuery.each(form, function(i, e) {
formdata[e.name] = e.value;
});
$.ajax({
url:'/',
type:'POST',
contentType : 'application/json; charset=utf-8',
data: JSON.stringify(formdata)
}).done( (data) => {
console.log("success");
console.log(data);
$('#taskId').val(data);
}).fail( (data) => {
console.log("fail");
console.log(data);
});
}
/*--------------------------------
* タスクを停止
--------------------------------*/
function stopClick(){
alert("タイマーを終了します")
stopbtnOn();
$("#timerView").countdowntimer("stop", "stop");
var form = $('#TaskForm').serializeArray();
var formdata = {};
jQuery.each(form, function(i, e) {
formdata[e.name] = e.value;
});
$.ajax({
url:'/stop',
type:'POST',
contentType : 'application/json; charset=utf-8',
data: JSON.stringify(formdata)
}).done( (data) => {
console.log("success");
console.log(data);
}).fail( (data) => {
console.log("fail");
console.log(data);
});
}
/*--------------------------------
* ボタン制御:startボタンONの時
--------------------------------*/
function startbtnOn(){
$('#startButton').prop("disabled", true);
$('#stopButton').prop("disabled", false);
}
/*--------------------------------
* ボタン制御:stopボタンONの時
--------------------------------*/
function stopbtnOn(){
$('#startButton').prop("disabled", false);
$('#stopButton').prop("disabled", true);
}
まとめ
以上、初めてのSpringBootでのアプリケーション作成(実装編)でした。
とりあえず元の記事を見ながら作ってみよう、と始めたものなので細かいコードの意味などはまだ分からない箇所も多いのですが、実際に手を動かしたり調べながらやることですごくいい勉強ができたと思います。
初心者だけどWebアプリを作ってみたい!と思った方は、是非挑戦してみてください。