【JavaScript】jQuery

使い方

CDNを使用する方法

特徴:オンラインでのみ使用可能

// jQuery バージョン 3.71の場合
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
ダウンロードして使用する方法

特徴:オフラインでも使用可能
1.公式サイトからファイルをダウンロードする
Download jQuery | jQuery
※「名前を付けてリンク先を保存」でダウンロード

2.ファイルを配置する

3.ダウンロードしたファイルを外部取込する

<script src="/demo/resources/common/js/jquery-3.7.1.min.js"></script>

記入場所

パターン1:要素の下に記載する
<input type="text" id="name" value="あいうえお"/>

<script>
  alert($("#name").val())  // 「あいうえお」が表示される
</script>
パターン2:要素の上に記載する

$(function()をつけるとDOM Documentのロードが終わった際に実行されるようになる

<script>
  $(function() {
      alert($("#name").val())  // 「あいうえお」が表示される
  });
</script>

<input type="text" id="name" value="あいうえお"/>

要素の指定

すべて $("*")

すべての要素にマッチする

<script>
  $("*").css("font-family", "Arial");
</script>
ID $("#id")

指定したIDにマッチ

<script>
  // IDを指定
  $("#userId").css("color", "red");         // <p id="userId">~</p>
  // ID+エレメントを指定
  $("p#userId").css("color", "red");        // <p id="userId">~</p>
  // ID+クラスを指定
  $(".smpl#userId").css("color", "red");    // <p class="smpl" id="userId">~</p>
</script>
クラス $(".class")

指定したIDにマッチ

<script>
  // クラスを指定
  $(".smpl").css("color", "red");        // <h1 class="smpl">~</h1>
  // クラス+エレメントを指定
  $("p.smpl").css("color", "red");       // <p class="smpl">~</p>
  // クラスの組み合わせを指定
  $(".smpl.smpl2").css("color", "red");  // <p class="smpl smpl2">~</p>
</script>
エレメント $("element")

指定したエレメント要素(div等)にマッチ

<script>
  $("h1").css("color", "red");    // <h1>~</h1>
</script>
複数指定

カンマで区切ると、and条件でマッチ

<script>
  $("label,.smpl").css("color", "red");    // <label class="smpl">~</label>
</script>
○○○=~~~の形式のものを指定

id=○○やclass=○○など「=」を含むものが指定可能

<script>
  // id=~を持つすべての要素を指定(id以外になんでも指定可能)
  $("[id]").css("color", "red");
  // IDを指定
  $("[id='userId']").css("color", "red");    // <p id="userId">~</p>
  // クラスを指定
  $("[class='smpl']").css("color", "red");    // <p class="smpl">~</p>
  // 等しくないものを指定
  $("[id!='userId']").css("color", "red");    // <p id="userName">~</p>
  // 「-」前を指定
  $("[id|='user']").css("color", "red");    // <p id="user-id">~</p>
  // 含むものを指定
  $("[id*='user']").css("color", "red");    // <p id="userId">~</p>
  // 複数条件を指定
  $("[id*='user'][class='smpl']").css("color", "red");    // <p id="userId" class="smpl">~</p>
</script>
親子関係
<script>
  // 親要素を指定
  $("#userId").parent().css("color", "red");
  // 先祖要素をすべて指定
  $("#userId").parents().css("color", "red");
  // 子要素をすべて指定(1階層下)
  $("#userId").children().css("color", "red");
  // 子要素のエレメントを指定(1階層下)
  $("#userId").children("p").css("color", "red");
  // 子要素のエレメントを指定(全階層)
  $("#userId").find("p").css("color", "red");
</script>
順番
<script>
  // 最初の要素
  $("p").first().css("color", "red");
  // 最後の要素
  $("p").last().css("color", "red");
  //n番目の要素(最初は0)
  $("p").eq(0).css("color", "red");

</script>
is

obj の中から selector にマッチする要素が一つでもあれば true を、さもなくば false を返す
if文と合わせて使う

<script>
  // labelにid=userIdがあればアラートを出す
  if ($("label").is("#userId")) {
      alert("Find!");
  }

</script>
表示、非表示
<div id="hiddenItem" hidden>非表示</div>
<div id="visibleItem">表示</div>

<script>
  // hidden(非表示)の場合、アラートを出す
  if ($("#hiddenItem").is(":hidden")) {
      alert("Find!");
  }

  // visible(表示)の場合、アラートを出す
  if ($("#visibleItem").is(":visible")) {
      alert("Find!");
  }
</script>

イベント

(on)
イベント 内容
change フォーム部品の状態に何らかの変化があった時に発動
click 要素がクリックされた時に発動
blur / focus 要素にフォーカスが当たったとき(focus)、外れたとき(blur)に発動
load ドキュメントが読み込まれたあとに発動。読み込み前はreadyを使う
resize ウィンドウサイズが変化した時に発動
scroll 画面がスクロールした時に発動
keyup / keypress キーボードのキーが押された時(keypress)、離された時(keyup)に発動
mouseup / mousedown マウスのボタンが押された時(mousedown)、離された時(mouseup)に発動
mousemove 指定の要素内でマウスが動いている時に発動
submit フォームが送信された時に発動
error 何らかのJavaScriptエラーが発生した時に発動
<script>
  // クリック
  $("#nextButton").on("click", function() {
      alert("クリックされました!");
  });

  // 画面ロード後 ※$(function()で囲むと動かない
  $(window).on("load",function(){
      alert("Hello");
  });

  // クリックまたはマウスオーバー
  $("input").on("click change", function() {
      alert("クリックまたは変更");
  });

  // div内のinputを対象
  $("div").on("click","input", function() {
      alert("クリックまたは変更");
  });

  // 複数のイベント
  $("input").on({
      click: function() {
          alert("クリック");
      },
      mouseover: function() {
          alert("マウスオーバー");
      }
  });
</script>
その他
メソッド 内容
.val() 指定した要素の値を取得または設定
.text() 指定した要素のテキストを取得または設定
.prop() 指定した要素の属性を取得または設定(削除はremoveProp)
.css() 指定のCSSスタイルに変更
.remove() 指定した要素を削除
.addClass() 指定した要素にクラスを追加
.removeClass() 指定した要素にクラスを削除
<input type="text" id="userName" value="たかし"/>
<p id="sample">あいうえお</p>
<input type="radio" id="man" name="sex" value="1" /><label></label>
<input type="radio" id="woman" name="sex" value="2" checked/><label></label>

<script>
  // 値を取得
  $name = $("input#userName").val();
  alert($name);    // たかし
  // 値を変更
  $("input#userName").val("変更後");

  // テキストを取得
  $text = $("p").text();
  alert($text);    // あいうえお
  // テキストを変更
  $("p").text("変更後");

  // 属性(○○=××やchecked等)を取得
  // id属性の値を取得する例
  $id = $("p").prop("id");
  alert($id);    // sample
  // ラジオボタンがチェック済みか判定する例
  if($("#woman").prop("checked")){
    alert("女性");
  }
  // 属性(○○=××)を変更
  $("p").prop("id", "changed");
  // ラジオボタンのチェックをつける
  $("#woman").prop("checked","checked");
  // ラジオボタンのチェックを外す
  $("#woman").prop("checked","");

  // CSSを取得
  $color = $("#userName").css("color");
  alert($color);
  // CSSを変更
  $("#userName").css("color", "red");


</script>

$(this)

$(this)はイベントが発生した要素を指す

<p class="hoge">テキスト1</p>
<p class="hoge">テキスト2</p>
<p class="hoge">テキスト3</p>

<script>
$('.hoge').click(function(){
    $(this).css('color', 'red');    // ここでの$(this)はクリックされた要素だけを指す
});
</script>

each

jQuery.each() メソッド

jQuery オブジェクトをループ処理したい時
indexは省略可能

<p class="hoge">テキスト1</p>
<p class="hoge">テキスト2</p>
<p class="hoge">テキスト3</p>

<script>
  $("p").each(function(index) {
    if ($(this).text()=="テキスト2") {
        return true  // 次のループに行く(continueと同じ)
    }
    $(this).css("color", "red");  // テキスト2だけ色が変わらない
  });
</script>
<p class="hoge">テキスト1</p>
<p class="hoge">テキスト2</p>
<p class="hoge">テキスト3</p>

<script>
  $("p").each(function(index) {
    if ($(this).text()=="テキスト2") {
        return false  // ループ処理を終わる(breakと同じ)
    }
    $(this).css("color", "red");  // テキスト1だけ色が変わる
  });
</script>
.each() メソッド

引数で指定したオブジェクトをループ処理したい時
indexとvalは省略可能

<script>
  array = ["Apple", "Orange", "Grape"];

  $.each(array, function(index, val) {
      alert(index + ":" + val);  // 0:Apple 1:Orange 2:Grape
  });

</script>

【VBA】サンプル(Excelを開いて値を集計する)


Sheet1にコードを記載

Private Sub CommandButton1_Click()
    'エラーメッセージ
    Dim colErrMsg As New Collection
    
    '「メイン」シート
    Dim sheetMain As Worksheet
    Set sheetMain = ThisWorkbook.Sheets("メイン")
    
    '「集計結果」シート
    Dim sheetResult As Worksheet
    Set sheetResult = ThisWorkbook.Sheets("集計結果")

    'ディレクトリのパスを格納
    Dim colDir As New Collection
    
    'ファイルのパスを格納
    Dim colFile As New Collection
    
    '集計結果を格納
    Dim colResult As New Collection
    
    '一時的な値を格納
    Dim tmp As Variant
        
    '画面更新の非表示
    Application.ScreenUpdating = False

    '▼「集計結果」シートを初期化
    '2行目~最終行までクリア
    sheetResult.Rows(2 & ":" & Rows.Count).ClearContents

    '▼一覧のパスを取得
    For Each tmp In sheetMain.Range("inputDirList")
        If tmp <> "" Then
            colDir.Add tmp.Value
        End If
    Next

    '▼入力件数のチェック
    If colDir.Count = 0 Then
        '0件の場合エラー
        colErrMsg.Add ("対象のディレクトリを入力してください")
        GoTo ErrorEnd
    End If
    
    '▼ディレクトリ存在チェック+ファイルのパスを取得
    Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
    Dim f As Variant
    
    For Each tmp In colDir
        If dir(tmp, vbDirectory) = "" Then
            colErrMsg.Add ("ディレクトリが存在しません:" & tmp)
        Else
            For Each f In fso.GetFolder(tmp).Files
                colFile.Add (f.Path)
            Next
        End If
    Next
    If colErrMsg.Count <> 0 Then
        GoTo ErrorEnd
    End If
    
    '▼値を集計する
    Dim resultValue As New result
    Dim targetBook As Workbook
    
    '読み取り専用推奨メッセージを表示しない
    Application.DisplayAlerts = False
    
    For Each tmp In colFile
        '拡張子が"xlsx"のみ対象とする
        If fso.GetExtensionName(tmp) = "xlsx" Then
            'ブックを開く
            Set targetBook = Workbooks.Open(tmp)
            'ディレクトリを格納
            resultValue.dir = fso.GetParentFolderName(tmp)
            '名前を格納
            resultValue.name = targetBook.Sheets(1).Range("B2")
            colResult.Add resultValue
            Set resultValue = Nothing
            'ブックを閉じる
            targetBook.Close savechanges:=False
        End If
        
    Next
    
    '▼結果を出力する
    Dim i As Long
    i = 2
    For Each tmp In colResult
        sheetResult.Cells(i, 2).Value = tmp.dir
        sheetResult.Cells(i, 3).Value = tmp.name
        i = i + 1
    Next
    
    '▼「集計結果」シートを表示する
    sheetResult.Activate
    
    '▼処理終了メッセージを表示する
    MsgBox "集計処理が完了しました。", vbInformation
    
Exit Sub

'■エラー時の処理
ErrorEnd:
    Dim errMsg As String
    
    For Each tmp In colErrMsg
        If errMsg <> "" Then
            'エラーメッセージの改行
            errMsg = errMsg & vbCrLf
        End If
        errMsg = errMsg + tmp
    Next

    MsgBox errMsg, vbCritical
    
End Sub

クラスを作成してコードを記載
クラス名は「Result」とする

Public dir As String
Public name As String

【JavaScript】基本

記述方法

JavaScript のコードを記述するには script 要素を使用する
(HTML5以降)

<script>
// コードを記述する
</script>

記述場所

HTML ファイルの中の head 要素内、または body 要素内に記述する
※要素を取得する場合、取得する要素の後ろに記載しないと取得できない

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">

<script>
// コードを記述する
</script>

</head>
<body>

<script>
// コードを記述する
</script>

</body>
</html>

外部のjsファイルを読み込む方法

jsファイルの文字コードはHTML/JSPと合わせる、または
charsetにHTML/JSPと同じ文字コードつけること。
外部のjsには script の記載は不要。

<script src="/demo/resources/offer/js/common.js" charset="UTF-8"></script>
springで外部jsファイルを読み込む方法

1.servlet-context.xmlにresources配下を読み込む設定を記載する(デフォルトで記載あり)
servlet-context.xml

<resources mapping="/resources/**" location="/resources/" />

2.webapp>resources配下にjsファイルを配置する

3.コンテキストパス+jsファイルまでのパスを指定する
下記はコンテキストパスが「demo」の場合の例

<script src="/demo/resources/offer/js/common.js" charset="UTF-8"></script>

コメント

<script>
// 一行コメント

/*
   複数行
   コメント
 */
</script>

変数

変数名の重複が不可な「let」の使用を推奨

<script>

  // 変数
  var A1= 123;  // 数値 
  var A2= "あいえうお";  // 文字列(ダブルクォーテーション) 
  var A3= 'あいえうお';  // 文字列 (シングルクォーテーション)
  var A4;
  A4 = "あとから代入";

  // 変数(変数名の重複不可。その他はvarと同じため省略)
  let B= "定数のサンプル";

  // 定数
  const C= "定数のサンプル";

  // 使用不可な名前
  var 1st;  // 数字から始まる名前は使用不可
  var 123; // 数字だけの名前は使用不可
  var if;  // 予約語は使用不可

</script>

配列

<script>
  // 宣言
  const array = ["one", "two", "three"];

  // 使用
  console.log(array[0]); // => "one"

  // ループ
  for (let item of array){
    console.log(item);
  }

  // 追加(末尾に追加)
  array.push("D");

  // 削除(最後尾を削除)
  const poppedItem = array.pop(); // 最末尾の要素を削除し、その要素を返す
  console.log(poppedItem); // => "D"

  // 存在しない場合、undefinedを返す
  console.log(array[100]); // => undefined

  // 要素数を返す
  console.log(array .length); // => 3

</script>

Object

<script>

  // 空のオブジェクト
  const hoge = {};

  // 宣言時に初期値を設定
  const obj = {
      key: "value",
      123: 456,      // 数値の場合ダブルクォーテーション不要
      "my-key": "my-value"  // キーにハイフンを使いたい場合ダブルクォーテーションで囲む
  };

  // 使用方法
  console.log(obj.key); // => "value"
  console.log(obj["key"]); // => "value"  // これでも良い

  // ループ
  for (let item in obj){
    console.log(item);
  }

  // プロパティの追加
  // ※作成するキー(ここではnewKey)がオブジェクトになければ自動で作成される
  obj.newKey = "value";
  obj["newKey"] = "value";  // これでも良い

  // プロパティの変更
  // ※変更したいキーを選択する
  obj.newKey = "変更後value";
  obj["newKey"] = "変更後value";  // これでも良い

  // プロパティの削除
  delete obj.newKey;
  delete obj["newKey"];  // これでも良い

  // プロパティの存在確認
if ("key" in obj) {
    console.log("`key`プロパティは存在する");
}

</script>

Map

Objectとの違い
①キーにString以外を設定することができる
②キーの列挙順が保証されている
③要素数の取得が簡単
④直接的に反復処理が可能

<script>

  const map = new Map();
  // 新しい要素の追加
  map.set("key", "value1");
  // キーから値を取得
  console.log(map.get("key")); // => "value1"
  // 要素数の取得
  console.log(map.size); // => 1
  // キーの存在確認
  console.log(map.has("key")); // => true
  // 要素の削除
  map.delete("key");
  // 要素の削除(全部)
  map.clear();

</script>
<script>

  const map = new Map([["key1", "value1"], ["key2", "value2"]]);

  map.forEach((value, key) => {
      console.log(key+":"+value);
  });

</script>

比較演算子

厳密等価演算子(===)

同じ型で同じ値である場合に、trueを返す。

<script>

  console.log(1 === 1); // => true
  console.log(1 === "1"); // => false

</script>
厳密不等価演算子(!==)

異なる型または異なる値である場合に、trueを返す。

<script>

  console.log(1 !== 1); // => false
  console.log(1 !== "1"); // => true

</script>
等価演算子(==)

同じデータ型のオペランドを比較する場合は、厳密等価演算子(===)と同じ結果になる。

<script>

  console.log(1 == 1); // => true
  console.log("str" == "str"); // => true
  console.log("JavaScript" == "ECMAScript"); // => false
  // オブジェクトは参照が一致しているならtrueを返す
  // {} は新しいオブジェクトを作成している
  const objA = {};
  const objB = {};
  console.log(objA == objB); // => false
  console.log(objA == objA); // => true

  // 文字列を数値に変換してから比較
  console.log(1 == "1"); // => true
  // "01"を数値にすると`1`となる
  console.log(1 == "01"); // => true
  // 真偽値を数値に変換してから比較
  console.log(0 == false); // => true
  // nullの比較はfalseを返す
  console.log(0 == null); // => false
  // nullとundefinedの比較は常にtrueを返す
  console.log(null == undefined); // => true

</script>
不等価演算子(!=)

等しくないならtrueを返す。

<script>

  console.log(1 != 1); // => false
  console.log("str" != "str"); // => false
  console.log("JavaScript" != "ECMAScript"); // => true
  console.log(true != true);// => false
  // オブジェクトは参照が一致していないならtrueを返す
  const objA = {};
  const objB = {};
  console.log(objA != objB); // => true
  console.log(objA != objA); // => false

  console.log(1 != "1"); // => false
  console.log(0 != false); // => false
  console.log(0 != null); // => true
  console.log(null != undefined); // => false

</script>

if文

<script>

  let hoge= 1;

  if (1 == hoge) {
    alert("1です");
  } else if (2 <= hoge){
    alert("2以上です");
  } else {
    alert("その他です");
  }

</script>

switch文

<script>

  let hoge= 0;

  switch (hoge) {
  case 1:
    alert("1です");
    break;
  case 2:
    alert("2です");
    break;
  default:
    alert("その他です");
    break;
  }

</script>

for文

for (初期化式; 条件式; 増分式)

<script>

  let total = 0; // totalの初期値は0

  for (let i = 0; i < 10; i++) {
      total += i + 1; // 1から10の値をtotalに加算している
  }

</script>

while文

while文は条件式がtrueであるならば、反復処理を行う。

<script>

  while (条件式) {
      実行する文;
  }

</script>

do-while文

do-while文は実行後に条件の判定を行う。(一度は必ず通る)

<script>

  do {
      実行する文;
  } while (条件式);

</script>

関数

オーバーロード(引数違いの関数名)不可。

<script>

  // 関数宣言(引数あり、戻り値あり)
  function 関数名(仮引数1, 仮引数2) {
      // 関数が呼び出されたときの処理
      // ...
      return 関数の返り値;
  }
  // 関数宣言(引数あり、戻り値あり)
  function 関数名(仮引数1, 仮引数2) {
      // 関数が呼び出されたときの処理
      // ...
      return 関数の返り値;
  }
  // 関数宣言(引数なし、戻り値なし)
  function 関数名() {
      // 関数が呼び出されたときの処理
      // ...
  }
  // 関数宣言(これでも良い)
  var 関数名 = function(仮引数) {
      // 関数が呼び出されたときの処理
      // ...
      return 関数の返り値;
  }

  // 関数呼び出し(引数あり、戻り値あり)
  let 関数の結果 = 関数名(引数1, 引数2);

  // 関数呼び出し(引数なし、戻り値なし)
  関数名();

</script>

要素の取得

IDを指定(getElementById)

・同じIDが複数存在する場合は最初の要素しか取得しない
・存在しなかった場合は null が返る

<input type="text" id="hoge" value="サンプル"/>

<script>
  var hoge = document.getElementById("hoge");
  alert(hoge.value);
</script>
Nameを指定(getElementsByName)

・name属性は複数取れる => 一つでも要素番号を指定する必要あり
・foreachで回すの不可 => forで回す

<input type="text" name="hoge" value="サンプル"/>
<input type="text" name="hoge" value="サンプル2"/>

<script>
  var hoge = document.getElementsByName("hoge");
  alert(hoge[0].value);
  alert(hoge[1].value);

  for (var item of hoge) {
    alert(item.value);
  }
</script>
tagを指定(getElementsByTagName)

・複数取得できる=>nameと同じ要領

<input type="text" name="hoge" value="サンプル"/>
<input type="text" name="hoge" value="サンプル2"/>

<script>
  var hoge = document.getElementsByTagName("input");
  alert(hoge[0].value);
  alert(hoge[1].value);

  for (var item of hoge) {
    alert(item.value);
  }
</script>
クラス名を指定(getElementsByClassName)

・複数取得できる=>nameと同じ要領

<input type="text" class="hoge" value="サンプル"/>
<input type="text" class="hoge" value="サンプル2"/>

<script>
  var hoge = document.getElementsByClassName("hoge");
  alert(hoge[0].value);
  alert(hoge[1].value);

  for (var item of hoge) {
    alert(item.value);
  }
</script>
CSSセレクタを指定(querySelector、querySelectorAll)

・querySelectorは一つの要素を取得 => class等で複数取れても最初の一つだけ
・querySelectorAllは複数の要素を取得
・要素番号を指定する場合、[ ]で囲むこと => ( )は使用不可

セレクタ 対象
全称セレクタ すべての要素 *{}
要素セレクタ タグ名 h1{}
classセレクタ class属性の値 .hoge
idセレクタ id属性の値 #hoge
属性セレクタ 指定属性を持つ要素 a[title] {}
疑似要素セレクタ 選択された要素の一部 p::first-line {}
疑似classセレクタ 選択された要素の全体 button:hover {}
<input type="text" id="hoge1" class="smpl" value="サンプル"/>
<input type="text" id="hoge2" class="smpl" value="サンプル2"/>

<script>
  // IDを指定
  var hoge1 = document.querySelector("#hoge1");
  alert(hoge1.value);

  // classを指定
  var hoge2 = document.querySelectorAll(".smpl");
  alert(hoge2[0].value);

  // タグを指定
  var hoge3 = document.querySelectorAll("input");
  alert(hoge3[0].value);

</script>

複雑な指定




【Spring】JUnit、カバレッジ

事前準備(JUnit5)

Mavenでの設定
※java8以上のバージョンが必要
pomに下記を追加する
他のspringのライブラリとバージョンを合わせるため${org.springframework-version}と記載

  <dependencies>
 ~~~~~~~~~~~~~~~~~
    <!-- Spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${org.springframework-version}</version>
      <scope>test</scope>
    </dependency>

    <!-- Test -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.8.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.8.2</version>
        <scope>test</scope>
    </dependency>
 ~~~~~~~~~~~~~~~~~
  </dependencies>

テストクラスの作成方法

テストしたいクラスを右クリックして新規>その他を選択



testフォルダにクラスが作成される

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class OfferServiceTest {

    @Test
    void testAdd() {
        fail("まだ実装されていません");
    }

}

テストコードの記述(JUnit5)

DIする場合は@SpringJUnitWebConfig(classes = クラス名.class)または
@ExtendWith(SpringExtension.class)と@ContextConfiguration(classes = クラス名.class)をつける

@SpringJUnitWebConfig(classes = OfferService.class)
//下記でも可能
//@ExtendWith(SpringExtension.class)
//@ContextConfiguration(classes = OfferService.class)
class OfferServiceTest {
    @Autowired
    OfferService service;

    @Test
    void testAdd() {
        // 期待値
        int expected = 3;
        // 試験実施
        int actual = service.add(1, 2);
        // 検証結果
        assertEquals(expected, actual);
    }

}

アサーションの種類(JUnit5)

assertEquals 2 つの値が等しいかどうかをテスト
assertTrue 引数の値が true かどうかをテスト
assertFalse 引数の値が false かどうかをテスト
assertNull 引数の値が null かどうかをテスト
assertNotNull 引数の値が null でないかどうかをテスト
assertSame 2 つの参照が同じインスタンスかどうかをテスト
assertNotSame 2 つの参照が異なるインスタンスかどうかをテスト
assertArrayEquals 2 つの配列が等しいかどうかをテスト
assertThrows 指定した関数が例外をスローするかどうかをテスト
assertNotEquals 2 つの値が等しくないかどうかをテスト
assertThat 値が指定された条件を満たすかどうかを確認
assertThrows 例外がスローされるかどうかを確認
assertDoesNotThrow 例外がスローされないかどうかを確認
assertTimeout 指定された時間内に実行が終了するかどうかを確認
assertTimeoutPreemptively 指定された時間内に実行が終了するかどうかを確認
assertLinesMatch 2つの文字列が一致するかどうかを確認
assertAll 複数のアサーションをまとめて確認

JUnitの実行(JUnit5)

JUnitのバージョンの確認(初回)

テストクラスで「右クリック」>「実行」>「実行の構成」を選択

テスト・ランナーがJUnit5になっていることを確認

指定したテストメソッドを実行

テストしたいメソッド名で「右クリック」>「実行」>「JUnitテスト」を選択

結果が表示される

テストクラス内の全メソッドを実行

クラス名で「右クリック」>「実行」>「JUnitテスト」を選択

結果が表示される

カバレッジ

「右クリック」>「カバレッジ」>「JUnitテスト」を選択

カバレッジが100%でないと、通っていない処理がある

緑色:実行された行
黄色:実行されているがパターンが網羅されていない行
赤色:実行されていない行

Spring、Struts2、SAStrutsの違い

早見表

Struts2 SAStruts Spring
画面遷移 struts.xmlで指定 URLに合ったActionクラスが実行 @RequestMapping等で指定
画面の値を受けとる方法 クラス変数に自動的に格納 クラス変数に自動的に格納(@ActionForm) @ModelAttributeや引数など
画面に値を渡す方法 クラス変数に格納 クラス変数に格納 model.addAttributeで格納

画面遷移

Spring

アノテーション(@RequestMapping/@PostMapping/@GetMapping)で遷移先を指定する
jspjava
・formactionで遷移先URLを指定

<form:form method="post">
    <input type="submit" value="確認へ進む" formaction="offer_confirm"/>
</form:form>

javajsp
・@Controllerのついたクラスを用意する
・@Post/GetMappingでURLに紐づくメソッドを用意する
・returnで開くjspを指定する

@Controller
public class ConfirmOffer {

    // コンテキストルート+offer_confirmのURLの場合、これが実行される
    @PostMapping("offer_confirm")
    public String confirm(Model model) {

        // confirmOffer.jspを開く
        return "confirmOffer";
    }
}
Struts2

struts.xmlで実行するメソッドや表示するjspを指定する
jspjava
・actionでstruts.xmlに紐づく名前を指定する

<s:form action="hello">
    <s:submit value="HelloWorldページへ行く" />
</s:form>

struts.xml
jspで指定した名前に紐づく定義のクラス、メソッドが実行される
(HelloWorldActionクラスのexecuteメソッドが実行)

<struts>
    <package name="default" extends="struts-default">
        <action name="hello" class="sample.HelloWorldAction" method="execute">
            <result name="success">/jsp/HelloWorld.jsp</result>
        </action>
    </package>
</struts>

javajsp
struts.xmlで指定したメソッドが実行される
・returnの値がstruts.xmlに紐づき、表示するjspを指定する

public class HelloWorldAction {
    public String execute() {
        // struts.xmlに紐づく値を返す
        return "success";
    }
}

struts.xml
・result nameがメソッドの戻り値と紐づく、表示するjspを指定する

<struts>
    <package name="default" extends="struts-default">
        <action name="hello" class="sample.HelloWorldAction" method="execute">
            <result name="success">/jsp/HelloWorld.jsp</result>
        </action>
    </package>
</struts>

値の受け渡し

Spring

jspjava
・modelAttributeを使用することでjava側でまとめて受け取れる

<form:form modelAttribute="offerForm" method="post">
    <label>ユーザーID:</label>
    <form:input path="userId"/><br>
    <label>名前:</label>
    <form:input path="name"/><br>

    <input type="submit" value="確認へ進む" formaction="offer_confirm"/>

    <input type="hidden" name="hiddenItem" value="hiddenValue">
</form:form>

javajsp
・ @ModelAttributeを使うとFormで取得可能
・model.addAttributeでjspに渡せる

@Controller
public class ConfirmOffer {

    @PostMapping("offer_confirm")
    public String confirm(Model model,
            @ModelAttribute("offerForm") OfferForm form, // formの値を取得
            @RequestParam(name="userId") String id,      // これでも取得可能
            String hiddenItem    // これでも取得可能
            ) {

        // jspに値を渡す
        model.addAttribute("offerForm", form);

        return "confirmOffer";
    }
}
Struts2

クラス変数を用意しておくと自動で画面の値がセットされる
jspjava
jspの項目のnameとクラス変数の名前は合わせておくこと

<s:form action="hello">
    <s:textfield name="name" />
    <s:submit value="HelloWorldページへ行く" />
</s:form>

・クラス変数とそのgetter/setterを用意しておくことで自動で値が入る
jspに渡す処理は不要

public class HelloWorldAction {

    public String execute() {
        System.out.println(name);
        return "success";
    }

    // jspの変数名と同じ名前でクラス変数を用意
    private String name;

    // getterを用意しておくこと
    public String getName() {
        return name;
    }
    // setterを用意しておくこと
    public void setName(String name) {
        this.name = name;
    }
}

javajsp
javaのgetterが実行される

    <body>
        <s:property value="name" />さん
    </body>

【SAStruts】基礎

ディレクトリ構成

全体構成
パス 説明
src/main/java/ javaのソースファイルが保存されているソースフォルダ
src/main/resources/ 設定ファイル等が保存されているソースフォルダ
src/main/webapp 公開用のファイルを保存するためのフォルダ(配下のWEB-INFを除く)
src/main/webapp/WEB-INF/view/ jspを保存するためのフォルダ
Javaフォルダ構成(src/main/java/)
パッケージ名 説明
action Actionクラスを保存するためのパッケージ
service Serviceクラスを保持するためのパッケージ
dto Dtoクラスを保存するためのパッケージ
entity entityクラスを保存するためのパッケージ
form ActionFormクラスを保持するためのパッケージ
utill utillクラスを保持するためのパッケージ
リソースフォルダ構成(src/main/resources/)
ファイル名 説明
app.dicon 他のdiconファイルをコンテナに登録するために読まれるファイル
application_ja.properties アプリケーション内で使用するメッセージ等を保存するファイル(日本語ロケーション)
application.properties アプリケーション内で使用するメッセージ等を保存するファイル
convention.dicon アプリケーションのネーミング規約を定義するファイル
creator.dicon ネーミング規約に基づいてコンポーネント定義を作成するCreatorを定義するファイル
customizer.dicon Creatorが作成したコンポーネント定義をカスタマイズするCustomizerを定義するファイル
env_ut.txt S2Unitを使った単体テスト用の環境を定義するファイル
env.txt 実行環境を定義するためのファイル
jdbc.dicon DBの接続先等の設定を記載するためのファイル
log4j.properties ログの出力を設定するためのファイル
s2container.dicon S2コンテナをカスタマイズするための設定を定義するファイル
s2jdbc.dicon S2JDBCの設定を記載するためのファイル

URLとActionの関係

・URLに紐づくActionクラスのメソッドが自動で実行される。
  例.http://localhost:8080/sa-struts-tutorial/addの場合
   ⇒「AddAction」クラスの「index()」メソッドが実行される
  例.http://localhost:8080/sa-struts-tutorial/add/testの場合
   ⇒「AddAction」クラスの「test()」メソッドが実行される
・実行するメソッドには「@Execute」をつける。
  パラメータのバリデータを実行する場合
   ⇒@Execute(validator = true, input = "index.jsp")
    ※inputにはエラー時に遷移する画面を指定。validator = trueは省略可能
  パラメータのバリデータを実行しない場合
   ⇒@Execute(validator = false)
・メソッドは引数は設定せず、戻り値は「String」で定義して遷移先のパスを返す。
  http://localhost:8080/sa-struts-tutorial/add/で実行したメソッドの戻り値がresult.jspの場合
   ⇒「WEB-INF->view->add->result.jsp」が開く

値の受け渡し

・画面のFormの値は「@ActionForm」をつけたフォームで受け取る。
・Formの変数はpublicで宣言する。getter/setterは不要。(privateでgetter/setterにしても良い)
・変数にアノテーションをつけてバリデータを実行(@Executeで指定)可能。
  @Required ⇒ 必須チェック
  @IntegerType ⇒ 数字チェック

DI

・クラス全般に「@Resource」をつける。@ResourceはDIする意味。
コンポーネントスキャン(DIコンテナに登録すること)の範囲は「convention.dicon」で管理。
・シングルトン?
 ⇒ SAStrutsはリクエスト単位で管理。問題なくクラス変数を使用できる

サンプル



Action

public class AddAction {

    public Integer result;

    @ActionForm   // Formにはこれをつける
    @Resource     // クラスはDIして使用する
    protected AddForm addForm;

    @Execute(validator = false)
    public String index() { 
        return "index.jsp";
    }

    @Execute(input = "index.jsp") // バリデータを実行する。エラー時にindex.jspを開く
    public String submit() { 
        result = Integer.valueOf(addForm.arg1) + Integer.valueOf(addForm.arg2);
        return "result.jsp";
    }
}

Form

public class AddForm {

    @Required
    @IntegerType
    public String arg1;

    @Required
    @IntegerType
    public String arg2;
}

jsp(入力画面)

<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Add</title>
<link rel="stylesheet" type="text/css" href="${f:url('/css/sa.css')}" />
</head>
<body>

<h1>Tutorial: Add</h1>

<html:errors/>
<s:form>
<html:text property="arg1"/> +
<html:text property="arg2"/>
<input type="submit" name="submit" value="サブミット"/>
</s:form>
</body>
</html>

jsp(結果画面)

<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Add</title>
<link rel="stylesheet" type="text/css" href="${f:url('/css/sa.css')}" />
</head>
<body>

<h1>Tutorial: Add</h1>

<html:errors/>
${f:h(arg1)} + ${f:h(arg2)}
= ${f:h(result)}<br />
</body>
</html>

【SAStruts】環境構築(チュートリアルの実行)

チュートリアルファイルをダウンロードする

Super Agile Struts - Download

Eclipseでインポートする



プラグインをインストールする(動かすだけなら不要そう)

メニューバーの「ヘルプ」⇒「新規ソフトウェアのインストール」を開く
作業対象:http://eclipse.seasar.org/updates/3.3/

プロジェクト・ファセットの設定

動的Webモジュールに変更する

必ず「適用して閉じる」をすること(デプロイメント・アセンブリーが出ない)

デプロイメント・アセンブリーの設定






エラーの解消


各diconファイルを開き、「http」⇒「https」に変更する