20200714のJavaに関する記事は11件です。

TDD勉強#2(July 13th, 2020)

新しい知識

assertTrue(boolean)

引数がtrueかどうか判別する.

Object.equals

public boolean equals(Object object){
    return true;
}

参考記事
https://engineer-club.jp/java-equals

型キャスト

対象の変数の直前に(型名)を付与する.

long l = 1026;
int i = (int) l;

参考記事
https://java-code.jp/66

クラスの継承

継承なしのクラス

public class School{
    String name;
    int id;
    attend(){}
    test(){}
}

継承すると,

public class Student{
    String name;
    int id;
    attend(){}
}
public class School extends Student{
    test(){}
}

もとのクラス(student)を親クラス,スーパークラス,継承したクラス(school)をサブクラスという.
・オーバーライド
→スーパークラスのメソッドをサブクラスで上書きすること.

参考記事
https://techacademy.jp/magazine/9246

アクセス修飾子

public
どこからでもアクセス可能.一つのファイルに一つだけ.ファイル名とクラス名は同じである必要がある.

protected
そのクラスを継承したサブクラス内部からアクセス可能.

private
クラス内部からのみアクセス可能.

リフレクション

getClass().インスタンス変数でクラス情報のインスタンスを取得する.(意味不明)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

新卒一年目のプログラマが感動したEclipseショートカット11選

こんにちは。よよよです。今回は自分用チートシートも兼ねて、便利なEclipseショートカットを集めました。

Eclipseショートカット集11選

Ctrl + Shift + R・・・リソースの検索

→新しくファイルを開きたい時によく使用します。

Ctrl + Space・・・予測変換

→予測変換。

Ctrl + F・・・ソース検索

→特定文字列を検索。変数名、メソッド名の確認等に使えます。

Ctrl + Shift + /・・・複数行のコメント

Ctrl + H・・・検索ダイアログの表示

Ctrl + E・・・Eclipse内で開いているタブの一覧を表示

→素早く作業ファイルを変更したい時に重宝します。

Ctrl + O・・・メンバの概要を表示

→フィールドやメソッドの概要を知りたい時に使えます。

Ctrl + Shift + W・・・開いているタブを全て閉じる

alt + Shift + A・・・選択範囲を同時にインデント

→インデントを一行づつ行う必要がなくなります。

Ctrl + alt + H・・・メソッド/コンストラクタの呼び出し階層の検索

→呼び出し元を検索できるほか、メソッド内で呼び出しているメソッドを把握することも出来ます。メソッドが何お処理に使われているかを手っとり早く知る事が出来ます。

メソッドを選択してF3・・・宣言部分へ移動

→メソッドの中身を知りたい時によく使用します。

2020年7月14日 作成
メモ書きなのでもし間違ってたら申し訳ないです。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

政府の接触確認アプリ(COCOA)の機能を補完するアプリを作ってみた(3密チェッカー)

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/33a241c4-5ff6-b793-6e7c-c4c05d52debf.png

はじめに

私は、ラビットプログラムの名前でAndroidスマートフォン向けアプリを開発・公開している19歳の学生です。
去年スマホアプリ開発コンテスト アプリ甲子園 2019に「ピックアップ通知音」アプリを応募して、特別企業賞 マイナビ賞を受賞しました。
https://www.applikoshien.jp/report/2019.html
あれから半年ほど経って最近これといったものを作っていなかったのですが、今COVID-19が流行っているので何かこれを題材にした新しいアプリが作れないかと考えていました。

その間に、5月あたりから報道されていた「接触確認アプリ」(COCOA)が公開されて実際に使ってみたのですが、何か味気ないというか、物足りないと感じたので、足りないと感じた部分を補完するアプリを自分で作ってみました。

そしてQiitaの接触確認アプリ関連の記事が話題になっていたので、私も負けずに書いてみました:grin:
https://qiita.com/Anharu/items/c00e882d678538be0ab0

なぜ1から作ったのか

COCOAはオープンソースなので、誰でも開発に参加することができます。
ですが、COCOAはできるだけ多くの国民の方に使ってもらえるようにと考えられて作られたものなので、できること・取得する情報が制限されています。
実際には個人情報を取得しないアプリなのに問題視されることが多いので、下手に機能を増やすだけだとかえって利用者数が減ってしまう恐れがあります。
そこで、COCOAとは別にアプリを作ることで、もっと多くの情報を得たいと思う人だけが使えるものになったらいいと思い、この考えに至りました。

また、COCOAはみんながインストールしていないと機能しませんが、このアプリは自分だけインストールすればすべての機能が使えるところにとてもこだわりました!
相手の判別はビーコンではなくMACアドレスで行うので、相手はBluetoothがオンの状態であるだけでOKなんです:ok_hand:

開発環境について

私はいつもと同じくAndroid Studioを使ってJavaで作りました。
COCOAはXamarinで作られているようですが、1からアプリを作れるほどの技術がなかったです...
本当はiOS版も作りたかったのですが、同じ理由で現在はAndroidのみです。
また、とにかく早く作り上げたかったので、特別難しいことはしていません。
COCOAではAppleとGoogleが共同で開発したAPI「Exposure Notification」を使用してメイン機能を実装していますが、このアプリはこのAPIは一切使用していません。
というか、個人がこのAPIを自由に使用することはできないようになっています。


ここからは、私が作ったアプリの機能と実装にあたって工夫した点を、少しコードを交えながらご紹介します。
できるだけ分かりやすくするために画像も付けたので、一緒にご覧ください!
:point_right: このアプリはGoogle Playに公開しているものです。もしよろしければダウンロードして使ってみてください!
:iphone: https://play.google.com/store/apps/details?id=rabbitp.check.threec

ホームタブ

アプリを起動してまず表示される画面です。
この画面では、今日と昨日の合計すれちがい・密接人数と、バックグラウンドの動作状態を確認することができます。
バックグラウンド状態のところには、次の測定時間と最後に測定したときの3密状態が表示されます。
また、「今すぐ3密状態をチェック」ボタンをタップすると、次回測定時間まで待たなくてもすぐに調べることもできます。
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/f7b8c336-9833-42a5-6484-065380b496bb.png
今すぐ3密状態をチェックするを押して測定した様子はこちらです。
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/7747ee84-6a48-3651-e290-7bb435a57f07.png

今すぐ3密状態をチェックするときのプログラムと、バックグラウンドで測定するときのプログラムは、時間を指定して自動実行するかどうかの違いだけであとはほとんど同じです。

測定する項目について

15分おきの自動測定や、「今すぐ3密チェック」ボタンを押したときは次の項目を測定しています。

:convenience_store: 密閉 → マイクで騒音レベルを調べる

騒音レベルが40dBを超えた場合、密閉と判定します。

:family: 密集 → Bluetoothデバイス数を調べる

デバイス数が40台を超えた場合、密集と判定します。

:two_men_holding_hands: 密接 → 近接Bluetoothデバイス

RSSI(電波強度)が-55以上のデバイス数が3台を超えた場合、密接と判定します。

:satellite_orbital: 位置情報 → GPSで緯度と経度を調べる

自動測定時のみ、測定場所を記録しておきます。
「危険度分布マップ」機能は、この情報をもとに地図上にピンを立てます。

:abc: BluetoothデバイスのMACアドレス

MACアドレスを調べることで既に検出済みデバイスかどうかの判定ができるので、同じデバイスをカウントしないようにするために記録しておきます。
この記録は1日ごとにリセットされます。

Exposure Notification APIは使えない

本日より、Exposure Notification の提供を開始します。
同技術は公衆衛生機関が利用でき、Android 及び iOS 搭載端末上で動作します。

引用元:https://japan.googleblog.com/2020/05/apple-google-exposure-notification-api-launches.html

COCOAアプリは、接触者検知や通知といった処理をExposure Notification APIに任せています。
COVID-19に感染した人の濃厚接触者を追跡するために開発されたこのAPIは、利用範囲が公的機関に限定されているため個人利用ができません。
そのため、3密の測定をするには他の方法で行わなければいけません...
IMAGE ALT TEXT HERE
APIについての参考動画(日本語訳):https://www.youtube.com/watch?v=jRIOwmywuQE

Exposure Notificationを使用しない測定方法について

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/be8171d6-213b-3a6b-9b67-bcd4ebcb4dd8.png
※画像は「接触確認アプリ及び関連システム仕様書」の文章の一部
やりたいことは、周りのデバイス数とCOCOAをインストールしている人数の測定です。
仕様書を見る限りこのAPIを使わないとバックグラウンドではBluetooth(BLE)検索ができないと思われがちですが......

問題1:BLEとバックグラウンドの相性

実際試してみると、普通にBluetoothもBLEもバックグラウンドで検索できることが分かりました!(あっさり解決!!!)
なので、APIを使わなくてもBluetooth検索をしてデバイス数をカウントすれば密集人数を調べられます。
また、RSSI(電波強度)を調べれば近くにあるかどうかもわかるので、密接人数も調べることができます。
Serviceを継承したクラスに検索処理を書き、ActivityからstartForegroundService(APIレベル26未満の場合はstartService)を呼べば実行できます。
※startForegroundServiceの場合は、開始から5秒以内にstartForegroundをServiceクラス内で呼ぶ必要があります。→詳しくはこちら

問題2:UUID取得できない、startScan勝手に終わらない!

先に結論を言うと、私はgetBluetoothLeScannerとstartScanを組み合わせて測定する方法で実装しました。
なぜ両方を使う必要があるのか... まずはこの表を見てください。

①BroadcastReceiverクラスを作ってstartDiscovery ②ScanCallbackクラスを作ってstartScan
バックグラウンド動作 ○ できる ○ できる
画面オフ時の動作 ○ できる △ 検索対象のUUIDを制限する必要がある
デバイス検索終了判断 ○ できる × 手動で止めないといけない
COCOA判別(UUID取得) × できない ○できる

①:https://www.hiramine.com/programming/bluetoothcommunicator/02_scan_device.html
②:https://www.hiramine.com/programming/blecommunicator/02_scan_device.html
それぞれ試してみて分かったことを表にまとめました。

①は画面オフ時でもバックグラウンド同様動作しますが、②はそのままやっても画面オフ時だけ動作しません。
これはAndroid8.1(APIレベル27)から仕様が変更になったことが原因だそうです。(参考サイト1参考サイト2
このページに書かれているように検索するUUIDを制限すれば、問題なく動作します。

①でデバイス検索が終了したとき、1度BroadcastReceiverが呼ばれるので、そこでintent.getAction()がBluetoothAdapter.ACTION_DISCOVERY_FINISHEDになったら終了したと分かりますが、②は見つけるたびにScanCallbackが呼ばれ続けるので終了判断ができません。(終わらせるためには時間指定などで手動で止める必要があります。)

①ではUUIDの取得ができません。(これについては詳しく分かってないです...参考サイトはここ?
②を使えば、UUIDを取得することができます。(詳しくはこちら

こうなるととても厄介です。
①だと対象がExposure Notificationかどうか判別できないし、②だと検索がひと段落した時に停止させることができません。
ならどうすればいいか、両方使えばいいんです!
①で密集・密接を調べるためのデバイス数測定を行い、②でCOCOAインストール人数を測定します。
また、周囲のExposure Notificationの信号の数は大体4秒で取得できることも分かりました。(Beacon Scopeというアプリで事前に調べました。)
つまり、②は検索開始から4秒経ったら止めるようにします。

周囲のデバイス数を測定するためのプログラム

startDiscoveryでBLE検索を開始し、変化があったらBroadcastReceiverが呼ばれます。

    ...省略

    //ブロードキャストレシーバーの登録
    context.registerReceiver(mBroadcastReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
    context.registerReceiver(mBroadcastReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));

    //Bluetoothアダプタの取得
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    scanner = mBluetoothAdapter.getBluetoothLeScanner();

    //スキャン開始
    mBluetoothAdapter.startDiscovery();

    ...省略

    //ブロードキャストレシーバー
    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent )
        {
            String action = intent.getAction();

            if( BluetoothDevice.ACTION_FOUND.equals( action ) )
            {
                //発見!!!
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String addmacaddress=device.getAddress();  //デバイスのMACアドレス
                int rssi=intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);  //デバイスの電波強度

                ...省略

                return;
            }

            //Bluetooth端末検索終了
            if( BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals( action ) )
            {
                try {
                    //スキャンの停止
                    mBluetoothAdapter.cancelDiscovery();

                    //ブロードキャストレシーバーの登録解除
                    context.unregisterReceiver(mBroadcastReceiver);


                    //次にCOCOAのインストール数を調べる
                    startScanBLE(context);

                }catch (Exception e){

                }

                return;
            }
        }
    };

COCOAのインストールデバイス数を測定するためのプログラム

startScanでBLE検索を開始し、変化があったらScanCallbackが呼ばれます。

    //Exposure NotificationのUUID
    String ExpNoti_UUID = "0000fd6f-0000-1000-8000-00805f9b34fb";
    //スキャン時間
    private static final long SCAN_PERIOD = 40000;
    //BLE機器のスキャンを行うクラス
    private BluetoothAdapter mBluetoothAdapter;
    //BLE機器のスキャンを別スレッドで実行するためのHandler
    private Handler mHandler;

    //デバイススキャンコールバック
    private static ScanCallback mLeScanCallback = new ScanCallback()
    {
        //スキャンに成功
        @Override
        public void onScanResult(int callbackType, ScanResult result)
        {
            BluetoothDevice device = result.getDevice();
            String MACaddress=device.getAddress();  //デバイスのMACアドレス
            int rssi=result.getRssi();  //デバイスの電波強度
            List<ParcelUuid> uuids = result.getScanRecord().getServiceUuids();

            if (uuids != null) {
                for (ParcelUuid uuid : uuids) {
                    //発見!!!(指定したUUIDの場合のみ)

                    ...省略

                }
            }


        }

        // スキャンに失敗
        @Override
        public void onScanFailed( int errorCode )
        {
            super.onScanFailed( errorCode );
        }
    };

    ...省略

    //スキャン開始(COCOAのインストール数を調べる)
    private void startScanBLE(Context context)
    {
        //Exposure NotificationのUUIDのみ調べる
        ScanSettings settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
        ScanFilter uuidFilter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(UUID.fromString(ExpNoti_UUID))).build();
        List<ScanFilter> scanFilters = new ArrayList<>();
        scanFilters.add(uuidFilter);

        //スキャン開始
        scanner.startScan(scanFilters, settings, mLeScanCallback);

        //指定した時間で検索終了
        mHandler = new Handler();
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //指定時間が経過したらScanCallbackを止める
                stopScanBLE(context);

                ...省略

            }
        }, SCAN_PERIOD);

    }

    ...省略

    //BLEスキャンの停止
    public static void stopScanBLE(Context context)
    {
        //一定期間後にスキャン停止するためのHandlerのRunnableの削除
        mHandler.removeCallbacksAndMessages( null );

        //BluetoothLeScannerの取得
        android.bluetooth.le.BluetoothLeScanner scanner = mBluetoothAdapter.getBluetoothLeScanner();
        if( null == scanner )
        {
            return;
        }
        scanner.stopScan( mLeScanCallback );
    }

長くなりましたが、これが測定のメインプログラムです。

詳細情報タブ

Spinner項目1:「蓄積データからの種類別グラフ」

測定データをもとに様々なグラフが表示されます。
上の2つは、3密の割合を示す円グラフです。
1つ目が今日の3密割合、2つ目が最大21日分の測定データから計算した3密割合です。
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/97b4729e-5a7c-b369-dbb7-ade88cb6cab7.png

下にスクロールすると、更に2つグラフが表示されます。

  • 「これまでの日別危険度」では、1日ごとに1密を1カウントとして全体の50%(毎時4回測定*24時間*3密*0.5=144カウント)を危険度100%として密割合を日別に表示しています。
  • 「1日の時間別割合」では、1時間ごとに3つ(密閉・密集・密接)の測定結果を足して、どの時間帯が危険だったかをぱっと見て分かるようにグラフ化しています。(そのまま足して一番値が大きいものを基準に表示しているので、単位はありません。)

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/4e1aa19f-16cb-f74d-4179-ada49f819c96.png

グラフの描画には、「MPAndroidChart」を使用しました。
https://github.com/PhilJay/MPAndroidChart
このライブラリ、とても便利でカスタマイズも容易なので、どんなグラフでも作れます!
データ自体は配列でセットするだけなのでとても分かりやすいです。
これは、「これまでの日別危険度」で表示しているように折れ線グラフを表示する例です。

build.gradle(appレベル)
...省略

dependencies {

    ...省略

    implementation 'com.github.PhilJay:MPAndroidChart:v2.2.5'
}

レイアウト
<com.github.mikephil.charting.charts.LineChart
    android:id="@+id/LineChart_21days"
    android:layout_width="match_parent"
    android:layout_height="200dp" />
プログラム
    LineChart LineChart_21days;

    ...省略

    LineChart_21days=view.findViewById(R.id.LineChart_21days);

    LineChart_21days.setNoDataText("グラフを描画しています...");
    LineChart_21days.setDescription("最大21日分の測定データから生成");
    LineChart_21days.setHighlightPerTapEnabled(false);  //タップしてハイライトを無効化
    LineChart_21days.getLegend().setEnabled(false);  //チャートラベル説明(左下のやつ)を非表示
    LineChart_21days.setScaleEnabled(false);  //ピンチイン・ダブルタップ拡大を無効化
    LineChart_21days.setDrawGridBackground(false);
    Legend legend3 = LineChart_21days.getLegend();
    legend3.setPosition(Legend.LegendPosition.BELOW_CHART_LEFT);

    //グラフに表示するデータの設定
    List<Entry> entries = new ArrayList<>();
    entries.add(new Entry("データ1", 0));
    entries.add(new Entry("データ2", 1));
    entries.add(new Entry("データ3", 2));

    LineDataSet lineDataSet = new LineDataSet(entries,"ラベル");
    lineDataSet.setDrawValues(true);
    lineDataSet.setColor(Color.parseColor("#FF5722"));  //折れ線の色
    lineDataSet.setLineWidth(2);
    lineDataSet.setDrawFilled(true);  //塗りつぶす
    lineDataSet.setFillAlpha(10);  //塗りつぶしの透明度
    lineDataSet.setFillColor(Color.parseColor("#FF5722"));  //塗りつぶしの色
    lineDataSet.setCircleColor(Color.parseColor("#FF5722"));  //外心の円の色
    lineDataSet.setCircleRadius(5);  //中心の円の半径
    lineDataSet.setCircleHoleRadius(3);  //外心の円の半径
    lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);  //なめらかな折れ線

    LineData lineData1 = new LineData(labels, lineDataSet);
    lineData1.setValueFormatter(new PercentFormatter());
    lineData1.setValueTextSize(17f);
    lineData1.setValueTextColor(Color.TRANSPARENT);

    LineChart_21days.animateXY(1000, 1000);  //表示アニメーション
    LineChart_21days.setData(lineData1);

Spinner項目2:「蓄積データからの危険度分布マップ」

自動測定したデータで1密以上だった場所にはマーカー(ピン)を立ててお知らせします。
マーカーは密状態を判別できるように色を変えています。
000188.png
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/7ef39698-0ab3-53c1-a55f-71a832ab2c37.png

マーカーをタップすると、いつの結果か等その時の測定データの詳細を確認することができます。
infowindow_R.png

この機能はGoogle Maps Android APIを使用して実装しています。
導入方法:https://qiita.com/yuishihara/items/8955582de6fa639eb504
マーカーをタップしたときに表示されるウィンドウを設定する:https://qiita.com/sho-h-ei/items/a40f813a5178e716fb8c

Spinner項目3:「過去20日分の詳細データ」

名前の通り、すべての測定結果を一覧で見ることができます。
2つ目のSpinnerで確認したい日付を選ぶと、上から順に0:00~23:45までの結果が書かれたCardViewが並びます。
ここには、測定時にGPSで取得した位置情報(緯度・経度)をもとに住所を市区町村名まで表示します。
何密かによって背景色を変えることで、見やすいように工夫しました。
card.png
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/78e85799-c5e8-b6d0-1119-ffdd90ef4b54.png

また、CardViewをタップするとその測定場所をGoogleマップで開くようにしました。
GoogleマップのURLに緯度と経度を入れるだけで簡単に表示できます。
https://www.google.com/maps?q={緯度},{経度}
例えば、名古屋駅を開くリンクはこう書きます:https://www.google.com/maps?q=35.171131,136.881499

共有タブ

まだ未完成です!!
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/a7a607af-8ca0-8382-6710-30d12431e937.png

最新情報タブ

一番上には、毎日17時くらいに更新される東京都の最新情報を、公式サイトから取得して表示しています。
取得に使用しているサイト:https://stopcovid19.metro.tokyo.lg.jp/
本当はJSON形式かCSV形式のデータを使いたいんですが、一部の情報はCSVで公開されているのですが、新規感染者数や前日比が載っていないので仕方なくホームページのHTMLを解析して取得するようにしました。
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/19272e42-faab-2a2c-b8b5-eeeaa25476e2.png
その下には、JSONで取得した都道府県別の新規感染者数をグラフ化して表示しています。
ただ、こちらは更新が遅いので数日前のものです。
データ取得に使用しているサイト(esriジャパン 新型コロナウイルス対応支援サイト):https://is.gd/Aj5sjK
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/c4fb9870-ad2b-c1fb-b52a-bece5fb1095a.png

ここまでが、アプリに今搭載している機能のすべてです。


Google Playで公開しています!

ぜひダウンロードして使ってみてください!!(紹介したすべての機能が使えます。)
レビューをいただけると幸いです:relaxed:
https://play.google.com/store/apps/details?id=rabbitp.check.threec
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/2fe97a7c-e5e7-1006-17e3-82b635dc175e.png
Google Play および Google Play ロゴは、Google LLC の商標です。

今後の改善点

  • 「過去20日分の詳細データ」のスクロールが遅いので直す
  • もうちょっと見た目をよくする
  • 共有タブを完成させる
  • COCOAをインストールしている端末は、15分おきにBluetoothのMACアドレスが変化し続けるので、何度もカウントしないようにする対策が必要

参考サイト

:disappointed_relieved: 本文中にもし間違いがあればご教授ください。よろしくお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javaエンジニアへの道 Part2 Javaってどんな言語なの?

こんばんは。
本日も夕飯までは基本情報技術者の学習に勤しみ、寝るまではJavaの学習をしている筆者です。

余談ですが、基本情報技術者の学習をしていて
「コード書くのって楽しいんだな・・・!」
と実感します(笑)

もちろん新しいことを知れるのはワクワクするのですが、定期的に眠気に襲われます(笑)
思い返すとコード書いてて眠くなったことないかもなー。

と言うことで、今日はJavaがどのような言語なのか、本当に簡単にまとめてみます。

Javaの特徴 〜大きく4つ!〜

①OSに依存しない!

webアプリを作ることもできれば、金融などのシステムを作ることもできる、汎用性の高い言語であると言えそうです。

②オブジェクト指向

Rubyなどのスクリプト言語同様にクラスベースの言語。しかし多重継承できないなど、スクリプト言語ほど、厳格なオブジェクト指向の言語ではなく、C言語のように手続き型プログラミングのスタイルでも記述ができる、やはり自由度の大きい言語の様です。

③コンパイルを必要とするコンパイラ言語!

Rubyなどから入るとこの辺りの知識は浅いなと自分でも思います。
コンパイルすることで、処理がスクリプト言語より早くなるようです。コンパイルは簡単に言うと、コードを2進数の表現に翻訳することですね。

④学習コストは少し高い

C言語などと比較すると難易度は下がると多いますが、それでもRubyやPythonに触れた後にやると、記述が多いなと思います(笑)

ということで・・・

本当に触りだけの知識になってしまいましたが、他の言語とも違いや仕組みなど、学習を始める段階で雰囲気は掴めたかなと思います。また学習を進めていく中で気になる点があったら、何度かまとめてみたいと思います!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Top 3 công nghệ lập trình giúp sinh viên IT

business-infographic-with-photo_23-2148340471.jpg

JavaScriptテクノロジー

JavaScriptは、1995年に作成された唯一のクライアント側スクリプト言語です。JavaScriptは非常に人気があり、インターネット上のほとんど
のWebサイトで使用されている非常に高いレベルのアプリケーションを備えています。高い双方向性を作成します。

Python、Javaと同様に、JavaScriptはWebプログラミング、モバイルアプリケーション、デスクトップアプリケーション、ゲームに使用されます。スライドショーに加えて、ポップアップ広告とGoogleのオートコンプリート機能もJavaScriptプログラミング言語で書かれた「優れた」ものです。

ビッグデータテクノロジー

ビッグデータは、従来のアプリケーションとツールの容量を超えるデータの集まりです。このテクノロジーは2001年から形成され、多くの重要なアプリケーションがあります。

企業の場合:ユーザーの行動データの収集に役立ち、企業は利益を増やすためにニーズに合わせたビジネスソリューションを提供できます。 EBay、Amazonのショッピングアプリケーションは、ビッグデータの製品です。 Software AG、Oracle、IBM、Microsoft、SAP、EMC、HP、Dellは、このテクノロジーのアプリケーションのリーダーです。

非政府組織の場合:ビッグデータは、データ分析活動、失業率の予測、将来のキャリアトレンドを大きくサポートします...

一方、このビッグデータソースは、人々がより良い買い物と消費体験をするのにも役立ちます。
Javaテクノロジー

Javaは、最も完全なプラットフォームとオブジェクト指向の独立性を持つ人気のあるプログラミング言語でもあります。この言語は1990年代に形成および開発されましたが、アプリケーションは密接で重要なため、これまでのところ「ホット」を減らしていません。

この言語は、電子商取引や科学的なウェブサイトの作成から、電子金融取引の分野でのアプリケーションまで、かなり多く使用されています。ゴールドマンサックス、シティグループ、バークレイズ、スタンダードチャータードなどのグローバル投資銀行は、Javaを使用して電子取引システム、検証および監査システム、データ処理プロジェクト、および多数のその他の重要な作業。 Java上のアプリケーションに加えて、ゲームアプリケーション、デスクトップアプリケーションなどを作成するための重要なコンポーネントとしても知られています。
おわりに
上記のテクノロジーの一部を使用して、教育、統計、販売、SEOなどの実際に適用します...
それらを使用して大きな成功を収めているWebサイトを参照してください。
地点:
=> https://soicau6868.net/soi-cau-888/
=> https://soicau6868.net/soi-cau-rong-bach-kim/
=> https://soicau6868.net/soi-cau-247/
読んでくれてありがとう

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

非推奨になったErrorControllerのgetErrorPathの対応

はじめに

こちらのissues/19844の要約記事

概要

Spring Boot 2.3.0以降から、
404などのエラーハンドリングで使用するErrorControllerのgetErrorPathが非推奨になった。

ErrorController.java
    /**
     * The return value from this method is not used; the property `server.error.path`
     * must be set to override the default error page path.
     * @return the error path
     * @deprecated since 2.3.0 in favor of setting the property `server.error.path`
     */
    @Deprecated
    String getErrorPath();

問題

コンパイル時に警告が出るくらい。
そもそもJavadocに記載されている通りで、該当メソッドをOverrideしても特に意味はない。
( server.error.pathの設定内容が有効なため )

ErrorControllerの実装クラス
    @Override
    public String getErrorPath() {
        return null;
    }

対応

修正対象

警告が気になる場合は@Deprecatedを付与して警告を消す。

ErrorControllerの実装クラス
    @Deprecated
    @Override
    public String getErrorPath() {
        return null;
    }

補足

ErrorControllerは実装しないとデフォルトのBasicErrorControllerが有効になるので注意。

ErrorMvcAutoConfiguration.java
    @Bean
    @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
    public BasicErrorController basicErrorController(ErrorAttributes errorAttributes,
            ObjectProvider<ErrorViewResolver> errorViewResolvers) {
        return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
                errorViewResolvers.orderedStream().collect(Collectors.toList()));
    }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring Bootで

Spring bootの公式チュートリアル(タスクのスケジュール)を参考に、タスクを定期実行するプログラムを作成しました。

環境

Apache Maven 3.6.3
OS: macOS Mojave バージョン10.14.6
テキストエディタ: Visual Studio Code(以下VSCode)
Java: 11.0.2

作成

まず、Spring Initializrを開き、以下の内容で土台を作成します。

スクリーンショット 2020-07-14 10.56.39.png

出来上がったzipファイルを解凍し、エディターで開きます。

pom.xmlに、以下の依存関係を追加します。

<dependency>
  <groupId>org.awaitility</groupId>
  <artifactId>awaitility</artifactId>
  <version>3.1.2</version>
  <scope>test</scope>
</dependency>

Awaitilityは、非同期システムテスト用のシンプルなドメイン固有言語(DSL)を提供するライブラリです。(Introduction to Awaitilityより)

src/main/java/com/example/schedulingtasks下に、ScheduledTasks.javaファイルを作成します。

内容は以下のとおりです。

ScheduledTasks.java
package com.example.schedulingtasks;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTasks {

    private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        log.info("The time is now {}", dateFormat.format(new Date()));
    }
}

fixedRateは、各呼び出しの開始時刻から測定された、メソッド呼び出しの間隔を指定します。他にも、fixedDeleyといった、タスクの完了から呼び出しの間隔を指定するなどのオプションがあります。

@Scheduled
タスクを定期実行します。オプションをいろいろ選べます(下の表)。
定期実行したいtaskに実行周期をScheduledアノテーションで指定します。
このアノテーションが指定できるのは引数を取らないメソッドだけです。(コンパイルエラーにはなりませんが実行時に例外が発生します。)

今回はfixedRateで5秒おきにタスクを実行することにします。

field description
fixedDelay メソッドの前回の実行完了時刻から何ミリ秒後に実行するか。
fixedRate メソッドの前回の実行開始時刻から何ミリ秒後に実行するか。
initialDelay メソッドの初回実行時の待機時間。
cron cronを記述してスケジュールを設定。zoneを使用して時間帯の指定も可能。

(cron="・・・")を使うとより高度な設定もできます。

LoggerとLoggerFactoryはconsoleに結果を出力するためのものです。
LoggerFactory.getLogger()の引数にクラスを指定するとログを表示できます。

次に、src/main/java/com/example/schedulingtasks/下に自動で作られたSchedulingTasksApplication.javaファイルにコードを追加します。

内容は以下のとおりです。

SchedulingTasksApplication.java
package com.example.schedulingtasks;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class SchedulingTasksApplication {

    public static void main(String[] args) {
        SpringApplication.run(SchedulingTasksApplication.class);
    }
}

@SpringBootApplication
これ1つで3つ分のアノテーションの働きをしてくれる便利なアノテーションです。以下の3つのアノテーションを含んでいます。

@Configuration
コンテキストに追加の Bean を登録したり、追加の構成クラスをインポートしたりできます。

@Bean
@Beanを記述したメソッドでインスタンス化したクラスを返すためのものです。

@EnableAutoConfiguration
Spring Bootの自動構成メカニズムを有効にします。

@ComponentScan
パッケージ内の他のコンポーネントや設定等を探し、コントローラを見つけるようにSpringに指示します。

@EnableScheduling
スケジュールを有効にします。

実行する

以上でコードは完成しました。
さっそく以下のコマンドで実行してみます。

./mvnw spring-boot:run

5秒毎にタスクが実行されています。
スクリーンショット 2020-07-14 10.32.52.png

依存関係も特に追加することなく、簡単に作ることができました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring Bootチュートリアル タスクのスケジュール

Spring bootの公式チュートリアル(タスクのスケジュール)を参考に、タスクを定期実行するプログラムを作成しました。

環境

Apache Maven 3.6.3
OS: macOS Mojave バージョン10.14.6
テキストエディタ: VSCode
Java: 11.0.2

作成

まず、Spring Initializrを開き、以下の内容で土台を作成します。

スクリーンショット 2020-07-14 10.56.39.png

出来上がったzipファイルを解凍し、エディターで開きます。

pom.xmlに、以下の依存関係を追加します。

<dependency>
  <groupId>org.awaitility</groupId>
  <artifactId>awaitility</artifactId>
  <version>3.1.2</version>
  <scope>test</scope>
</dependency>

Awaitilityは、非同期システムテスト用のシンプルなドメイン固有言語(DSL)を提供するライブラリです。(Introduction to Awaitilityより)

src/main/java/com/example/schedulingtasks下に、ScheduledTasks.javaファイルを作成します。

内容は以下のとおりです。

ScheduledTasks.java
package com.example.schedulingtasks;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTasks {

    private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        log.info("The time is now {}", dateFormat.format(new Date()));
    }
}

fixedRateは、各呼び出しの開始時刻から測定された、メソッド呼び出しの間隔を指定します。他にも、fixedDeleyといった、タスクの完了から呼び出しの間隔を指定するなどのオプションがあります。

@Scheduled
タスクを定期実行します。オプションをいろいろ選べます(下の表)。
定期実行したいtaskに実行周期をScheduledアノテーションで指定します。
このアノテーションが指定できるのは引数を取らないメソッドだけです。(コンパイルエラーにはなりませんが実行時に例外が発生します。)

今回はfixedRateで5秒おきにタスクを実行することにします。

field description
fixedDelay メソッドの前回の実行完了時刻から何ミリ秒後に実行するか。
fixedRate メソッドの前回の実行開始時刻から何ミリ秒後に実行するか。
initialDelay メソッドの初回実行時の待機時間。
cron cronを記述してスケジュールを設定。zoneを使用して時間帯の指定も可能。

(cron="・・・")を使うとより高度な設定もできます。

LoggerとLoggerFactoryはconsoleに結果を出力するためのものです。
LoggerFactory.getLogger()の引数にクラスを指定するとログを表示できます。

次に、src/main/java/com/example/schedulingtasks/下に自動で作られたSchedulingTasksApplication.javaファイルにコードを追加します。

内容は以下のとおりです。

SchedulingTasksApplication.java
package com.example.schedulingtasks;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class SchedulingTasksApplication {

    public static void main(String[] args) {
        SpringApplication.run(SchedulingTasksApplication.class);
    }
}

@SpringBootApplication
これ1つで3つ分のアノテーションの働きをしてくれる便利なアノテーションです。以下の3つのアノテーションを含んでいます。

@Configuration
コンテキストに追加の Bean を登録したり、追加の構成クラスをインポートしたりできます。

@Bean
@Beanを記述したメソッドでインスタンス化したクラスを返すためのものです。

@EnableAutoConfiguration
Spring Bootの自動構成メカニズムを有効にします。

@ComponentScan
パッケージ内の他のコンポーネントや設定等を探し、コントローラを見つけるようにSpringに指示します。

@EnableScheduling
スケジュールを有効にします。

実行する

以上でコードは完成しました。
さっそく以下のコマンドで実行してみます。

./mvnw spring-boot:run

5秒毎にタスクが実行されています。
スクリーンショット 2020-07-14 10.32.52.png

依存関係も特に追加することなく、簡単に作ることができました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【SpringBoot入門】Spring Securityで認証機能

目的

Spring Quickstart Guideを取り組み終えた方、SpringBootを学び始めた方、復習をしたい方に向けて、

公式ガイドSecuring a Web Applicationを実際に取り組み学んだことを共有します。

完成形を確認します。
トップページがあり、hereをクリックすると、
スクリーンショット 2020-07-13 11.59.12.png

ログインページに移動します。テストユーザー用のユーザー名とパスワードを入力し、Sign inボタンをクリックすると、
スクリーンショット 2020-07-13 11.59.27.png

認証された人しか閲覧できないページに遷移します。ログインされていない状態ではこの画面にアクセスは出来ません。
スクリーンショット 2020-07-13 12.00.36.png

開発環境、これまでのおさらいは以下になります。

開発環境
OS: macOS Mojave バージョン10.14.6
テキストエディタ: Visual Studio Code(以下VSCode)
Java: 11.0.2

QuickstartGuide
Building a RESTful Web Service編
Consuming a RESTful Web Service編
Accessing Data with JPA編
Handling Form Submission編
Securing a Web Application編

1.SpringBoot projectを始めよう!

まずは、spring initializr にアクセスします。

1.ADD DEPENDENCIESボタンをクリックして、Spring WebThymeleafを追加。
2.Artifact, Nameは、securing-webに変更。
3.Javaを11に変更。

そしてGENERATEボタンをクリックしてZipファイルをダウンロードします。

スクリーンショット 2020-07-13 13.17.09.png

ダウンロードしたZipファイルを展開したら準備完了です。

2.コードを追加しよう!

先ほどのフォルダをVSCodeで開きます。
拡張機能のJava Extension Packのインストールの推奨します。と言われるのでインストールしておきましょう。

スクリーンショット 2020-06-30 10.08.25.png

home.htmlを作成しよう!

src/main/resources/templates/ にhome.htmlファイルを作成します。

スクリーンショット 2020-07-13 13.29.09.png

公式を参考にコードを追加します。トップページになります。

home.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
  <head>
    <title>Spring Security Example</title>
  </head>
  <body>
    <h1>Welcome!</h1>

    <p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
  </body>
</html>

htmlタグの部分は、th:〇〇sec:〇〇と記述出来るようにする為のものです(thymeleafやSpringSecurityのタグを用いた記述方法が可能になる)。

では、追加したコードのthymeleafの記述について深掘りしていきます。

thymeleafとは、springbootで扱う事が出来るテンプレートエンジンです。th:〇〇と記述します。
日本語で書かれたthymeleafチュートリアルもあります!

th:href

aタグのhref属性にセットするタグです。記述の仕方は、th:href="@{}"です。
{}の中はパスを指定します。今回は/helloですので、タグをクリックすると、http://localhost:8080/helloに遷移する事になります。

hello.htmlを作成しよう!

src/main/resources/templates/ にhello.htmlファイルを作成します。

スクリーンショット 2020-07-13 14.21.54.png

公式を参考にコードを追加します。

hello.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
  <head>
    <title>Hello World!</title>
  </head>
  <body>
    <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
    <form th:action="@{/logout}" method="post">
      <input type="submit" value="Sign Out"/>
    </form>
  </body>
</html>

th:inlineは、タグのテキスト内に変数の値を展開する為のものです。表示したい変数を[[...]]で囲みます。
今回は、${#httpServletRequest.remoteUser}なので、認証されているユーザーの名前を表示するようになっています。

Sign Outボタンが押されると、/login?logoutにリダイレクトにされます。

MvcConfig.javaを作成しよう!

src/main/java/com/example/securingweb/ にMvcConfig.javaファイルを作成します。

スクリーンショット 2020-07-13 14.43.27.png

公式を参考にコードを追加します。

MvcConfig.java
package com.example.securingweb;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfig implements WebMvcConfigurer {

  public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/home").setViewName("home");
    registry.addViewController("/").setViewName("home");
    registry.addViewController("/hello").setViewName("hello");
    registry.addViewController("/login").setViewName("login");
  }

}

@Configurationアノテーションは、Springの色々な設定をJavaのコード上で行えるようにするためにクラスに付与するものです。(設定クラス)
WebMvcConfigurerインターフェースを実装したMvcConfigクラスを作成し、addViewControllersメソッドをオーバーライドしています。

registry.addViewController("/home").setViewName("home");

別のControllerを用意して、@GetMappingアノテーションを用いてView名をreturnするやり方するのではなく、
上記記述によって、

http://localhost:8080/homeというURLの時、home.htmlというテンプレートを参照するようになります。
URLとテンプレートがマッピングされるようにしているみたいです。
login.htmlの実装は後ほど。

pom.xmlにSpring Securityを追加しよう!

Spring Securityを使用する為に、pom.xmlに以下を追加してください。

Spring Securityとは、Webアプリケーションにセキュリティ機能を追加するためのフレームワーク。
認証、認可、一般的な悪用に対する保護の包括的なサポートを提供します。

pom.xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-test</artifactId>
  <scope>test</scope>
</dependency>

スクリーンショット_2020-07-13_15_32_20.png

WebSecurityConfig.javaを作成しよう!

src/main/java/com/example/securingweb/ にWebSecurityConfig.javaファイルを作成します。

スクリーンショット 2020-07-13 15.48.47.png

公式を参考にコードを追加します。

WebSecurityConfig.java
package com.example.securingweb;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .antMatchers("/", "/home").permitAll()
        .anyRequest().authenticated()
        .and()
      .formLogin()
        .loginPage("/login")
        .permitAll()
        .and()
      .logout()
        .permitAll();
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {

    String password = passwordEncoder().encode("password");

    auth.inMemoryAuthentication()
        .passwordEncoder(passwordEncoder())
        .withUser("user").password(password).roles("USER");
  }

  @Bean
  public PasswordEncoder passwordEncoder() {
      return new BCryptPasswordEncoder();
  }

}

追加したコードを深掘りしていきます。

@EnableWebSecurityWebSecurityConfigurerAdapterクラスの継承

WebSecurityConfig.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  // 省略
}

@EnableWebSecurityアノテーションを付与する事により、Spring Securityが有効になります。
そして、WebSecurityConfigurerAdapterという抽象クラスを継承しています。このクラスにある、configureメソッドをオーバーライドして、
ページのアクセス制限の有無を実装していきます。

②ページのアクセス制限を設定する

WebSecurityConfig.java
@Override
protected void configure(HttpSecurity http) throws Exception {
  http
    .authorizeRequests()
      .antMatchers("/", "/home").permitAll() // アクセス制限が必要のないURL
      .anyRequest().authenticated()  // その他URLは、認証が必要。認証済みではないとアクセスできない
      .and()
    .formLogin()
      .loginPage("/login") // ログイン画面もアクセス制限なし
      .permitAll() // 認証は不要
      .and()
    .logout()
      .permitAll(); // 認証は不要
}

configureメソッドをオーバーライドしています。
引数でHttpSecurityを受け取っており、httpリクエスト関連の部分についての設定を記述するためのメソッドになっています。
ログイン、ログアウト、その他のページのアクセス時に認証は必要であるのかどうかを設定しています。

③認証するユーザーの設定

この部分の実装は、公式ガイド通りに進めるとdeprecated(非推奨)と言われてしまいました。
ですので、少し違う実装になっています。

WebSecurityConfig.java
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

// パスワードをエンコード
String password = passwordEncoder().encode("password");

// インメモリの認証を行うための設定
auth.inMemoryAuthentication()
    .passwordEncoder(passwordEncoder())
    .withUser("user").password(password).roles("USER");
}

@Bean
public PasswordEncoder passwordEncoder() {
  return new BCryptPasswordEncoder();
}

PasswordEncoder passwordEncoder()は、パスワードのハッシュ化をする為のメソッドを定義しています。
そして、文字列のpasswordをString password = passwordEncoder().encode("password");の部分でハッシュ化しています。

AuthenticationManagerBuilderは、メモリ内認証を可能にする為のクラスで、

// インメモリの認証を行うための設定
auth.inMemoryAuthentication()
    .passwordEncoder(passwordEncoder())
    .withUser("user").password(password).roles("USER");
}

ここでそれを実装しており、認証するユーザーの設定を行っています。

login.htmlを作成しよう!

src/main/resources/templates/ にlogin.htmlファイルを作成します。

スクリーンショット 2020-07-14 10.45.45.png

公式を参考にコードを追加します。ログインページになります。

login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
  <head>
    <title>Spring Security Example </title>
  </head>
  <body>
    <div th:if="${param.error}">
      Invalid username and password.
    </div>
    <div th:if="${param.logout}">
      You have been logged out.
    </div>
      <form th:action="@{/login}" method="post">
        <div><label> User Name : <input type="text" name="username"/> </label></div>
        <div><label> Password: <input type="password" name="password"/> </label></div>
        <div><input type="submit" value="Sign In"/></div>
      </form>
  </body>
</html>

User NameとPasswordを入力する欄があります。
th:if="${param.error}は、ユーザー認証が失敗した時に表示される領域で、
th:if="${param.logout}は、サインアウトをした際に表示される領域となります。(hello.htmlでSign Outボタンが押された後に表示される)

3.実行してみよう!

アプリケーション実行の準備が出来たので確認しましょう。

ターミナルで以下のコマンドを入力してEnterしてください。

ターミナル
$ ./mvnw spring-boot:run

トップページが表示されます。

スクリーンショット 2020-07-14 13.34.37.png

hereをクリックすると、ログインページが表示されます。
スクリーンショット 2020-07-14 13.34.52.png

適当なUser NameとPasswordを入力してSign Inボタンを押してみると、
スクリーンショット 2020-07-14 13.37.30.png

ログインページが再表示され、エラーメッセージも表示されていますね。
次に、Uesr Nameにuser、Passwordにpasswordと入力してSign Inボタンを押してみると、

スクリーンショット 2020-07-14 13.39.23.png

認証された人しか閲覧できないページに遷移出来ました。
スクリーンショット 2020-07-14 13.39.23.png

Sign Outボタンを押すと、

スクリーンショット 2020-07-14 13.41.36.png

先ほどのログインページにリダイレクトされ、メッセージも表示されています。

お疲れ様でした。完成です!

参考サイト

User.withDefaultPasswordEncoder()のdeprecatedの代替案
【Spring Security はじめました】#2 ユーザー認証
Spring Security で「Hello World!」

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JSFのバージョンを確認する方法

簡単に確認できる方法を知っている方は教えてください

方法1. FacesContextクラスで確認する

  1. FacesContextクラスをimportしているクラスを探す
    1. $ grep -iIr import | grep FacesContext
  2. デバックしやすいクラスを選んでブレークポイントを張る
  3. デバックする
  4. ブレークポイントにきたらEclipseの[Expression]タブなどで以下の結果でバージョンを確認する
    1. FacesContext.class.getPackage().getImplementationVersion();
    2. FacesContext.class.getPackage().getImplementationTitle();

image.png

方法2. MANIFEST.MFを見る

/META-INF/MANIFEST.MFを開いてみる

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javaプロセスのログを削除後、ログが出力されなくなった

Linuxサーバ検証環境でログが蓄積していたのでファイル名を置き換えた
その後Javaプロセスを再起動したが思うようにログが吐かれない…

⇒rsyslogプロセスを再起動することで解消。
rsyslogのログ転送対象になっていたため、手動で削除した時に関連付けがおかしくなったのかもしれない。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む