Java読書会「Javaコードアンチパターン」を読む会(第1回)開催
2月28日(土)、Java読書会BOF主催のJava読書会「Javaコードアンチパターン」を読む会の第1回を開催しました。
- 「Javaコードアンチパターン 初級からプロまで知っておきたいミスと回避策 」(Tagir Valeev著、柴田芳樹訳、インプレス刊)
著者のTagir氏は、IntelliJ IDEAなどのプログラミングツールを開発・販売しているJetBrains社のエンジニアでJavaチームに所属、IntelliJ IDEAの静的解析機能の開発をしています。
Java読書会BOFの読書会恒例で、書籍の表紙、表紙のそで(折り返し部分の記述)から、推薦の言葉、目次、序文、まえがき、謝辞、著者紹介、本書についてをしっかりと朗読して第1章に入りました。
本書の第1章コード品質の管理 では、コードスタイル、静的解析ツール、テスト、カバレッジなどに触れられており、最近の主要な静的解析ツールの紹介も記載されています。カバレッジではミューテーションカバレッジにも言及しています。
読書会の議論では、IntelliJ IDEAを使っているなら個人環境で静的解析ツールを入れなくても強力なサポートが得られるから、CD・CIでサーバーでビルドするときに静的解析ツールのチェックを入れるのではといった話や、ミューテーションカバレッジとはどういう振る舞いをして、どのような効果が得られるのかという話、動的解析で言及のあるjavapathfinderは、名前から察したとおりNASA謹製で、利用経験のある参加者からはものすごい計算機リソース(メモリ)と時間を費やすとの経験談もありました。
1.3.2項 静的解析ツールの活用 では、int値に対するビットシフトで32bit左にシフトするという誤った記述の検査について、
int y = x << 32; 本文では クイックフィックスとして x << 0 に変更することが提案されています。これはコードの動作は変えないものの、問題の解決にはならないでしょう。
とあり、また訳注18では
int値を32ビット、・・・シフトさせようとすると元の値自身が返される
とありますが、Java言語仕様で、int値のビットシフトにおいては、右オペランドの値の下位5ビットしか使われないとの規定があることに気づかされました。非常に含蓄ある書籍と皆感じていました。
1.4節 自動テスト では、Clonableインタフェースの実装について例示していましたが、普段ほとんどClonableの実装を書くことはしていないので、ちょっと理解に時間を要しましたが、ここであらためてJavaの基本的な仕様を学ぶことができました。
とても些細なことですが、参加者の一人から、p.7の図1.2 Eclipseの画面キャプチャにおいてタイトルバーのアイコンがIntelliJのものになっているように見えるね、と気づきがありました。MacOS上の画面キャプチャですが、拡張子.javaがIntelliJに結びついている場合にあり得るのではということのようです。
と、この1章だけでもとっても濃い内容でした。
第2章では、Apache Avroという割と著名なオープンソース製品のコード記述でビットシフト演算子を用いて値を25%(4分の1)とするコード例が演算子の優先順位で誤っている例の紹介がありました。CPUの命令実行では除算演算よりもビットシフトが圧倒的に速いので、最適化を意図して記述したもののバグを持ち込んでしまったということです。ここで書籍では
最新のJVMで使われるJIT(Just-In-Time)コンパイラやAOT(Ahead-Of-Time)コンパイラは、機械コードを生成する際に乗算や除算をシフト演算子に書き換えられるので
とありましたが、本当にそうなの?ということで本読書会ではこれを実際に確認することが宿題となりました。
次回は、3月28日(土)開催です。 参加案内は、Webページ Java読書会BOF に掲載されております。
Java読書会「Spring徹底入門 第2版」を読む会(第15回)を終えて
Java読書会BOF 主催「Spring徹底入門 第2版」を読む会(第14回)を12月20日(土)に開催しました。
今回は、12章 Thymeleafの残りと14章チュートリアルの途中、エンティティの実装まで読み進めました。14章のチュートリアルは、参加者がそれぞれ持参のPCで実際にPostgreSQLのユーザー・データベース作成、Spring Bootのプロジェクトを作成してソースコードの打ち込みをしながら進めました。
チュートリアルにおいて引っかかったことなど
実際に手を動かしながら実施すると、書籍を読むだけでは気づかないことや引っかかる事項がいろいろと出てきます。これらを調べ議論しながら進めたことで知識が深まり知見が広がりました。
Spring Framework、Spring Bootのバージョン
先月2025年11月に、Spring Framework 7.0 および Spring Boot 4.0がリリースされました。 書籍で言及されているSpring Bootの構築は、Webサービスの Spring Initializr を利用して作成します。Spring Initializrで選択可能なSpring Bootバージョンは、最新バージョンと一つ前のマイナーバージョンで本日時点では 4.0.1または3.5.9 となっています。書籍のチュートリアルは Spring Boot 2.7を前提としていますが、事前に試した限りでは 3.5でも 一部修正をすればビルド・実行は可能でした。
修正:依存関係でthymeleaf-extras-springsecurity4 をthymeleaf-extras-springsecurity6 に修正
PostgreSQL ユーザー作成時のパスワード指定
書籍では、次のように mrs ユーザーを作成するPostgreSQLコマンドで、パスワードにmd5ハッシュコード化したものを指定しています。
CREATE ROLE mrs LOGIN
ENCRYPTED PASSWORD 'md586082399b5082acb54472ee195a57ce8' ...
PostgreSQLは、バージョン10あたりから ENCRYPTEDの指定は意味をなさなくなり(後方互換性のために残されている)、パスワード文字列がハッシュコードの場合はそのまま(再ハッシュせずに)パスワードとして保存されます。md5ハッシュを使用するときは、先頭にmd5を付け、その後ろにmd5ハッシュ文字列を指定します。指定可能なハッシュは、md5およびSCRAM-SHA256です。
ここで発生した問題は、書籍ではユーザーのパスワードを mrs と記載しているのですが、上述のCREATE ROLE文で指定しているパスワードのmd5ハッシュ文字列が、mrsをmd5ハッシュ化したものと一致しないことでした。書籍の通りユーザーを作成すると認証ができません。 世の中には、md5のハッシュから元の文字列を逆生成するWebサイトがあり、書籍のmd5ハッシュを入れたところ、mrsmrs と結果が十秒足らずで得られました。md5はかなり脆弱ですね。
ところで、PostgreSQLサーバーとはSSH接続でコマンドを実行するなら、パスワードを平文で指定してもいいのかなと思いましたが、この関連でインターネットを調べていたときに、コマンド実行履歴(history)で見れてしまうという点を見かけ、なるほどと思いました。とはいえ、平文をハッシュにするときをどうするか、もあるので平文パスワードを扱う場所をどこに限定するかは別途検討すべき事項と思いました。
LC_COLLATE と LC_CTYPE
データベースを作成するときのパラメータで、書籍ではどちらも "C" を指定していました。 LC_COLLATEは、文字列の並び順(照合順)を決める設定で、Cは、Unicodeの文字(コードポイント)のバイト順で判断するが、高速に動作し、ja_JP.UTF-8 を指定すると日本語の文字も考慮された並びとなるが、動作が遅くなるという模様です。
LC_CTYPEは、文字の種類を分類するための設定で、文字、数字、大文字、小文字などの区別をするものになります。Cは、ASCII文字範囲(英字)を分類します。
テーブル名 usr
なぜかテーブル名に usr と省略形を使っています。userではいけないのかな? と疑問に思いました。 これは、userとしてしまうと、SQL の予約語(CREATE USER ... のUSER)と衝突してエラーになってしまいます。 推奨の回避方法は、名前をuser以外にする(推奨は複数形のusersですが)、あまりよくない回避方法は"user"とクォートする、ただしこの場合、JPAが生成するSQLでもuserをクォートさせる設定を別途行う必要があり、筋が悪い回避方法となってしまいます。
複合キーのクラスReservableRoomId でequalsとhashCodeのオーバーライド
複合キーを使用するエンティティ(テーブル)で、複合キーを表すクラスは包含するキーの値が同じ場合はインスタンスが違っていても同値とする(equalsメソッドがtrueを返し、hashCodeメソッドが同じ値を返す)実装が必要です。
書籍では、次のようなequalsメソッドとhashCodeメソッドの実装をしています。
@Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ReservableRoomId other = (ReservableRoomId) obj; if (reservedDate == null) { if (other.reservedDate != null) { return false; } } else if (!reservedDate.equals(other.reservedDate)) { return false; } if (roomId == null) { if (other.roomId != null) { return false; } } else if (!roomId.equals(other.roomId)) { return false; } return true; }
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((reservedDate == null) ? 0 : reservedDate.hashCode()); result = prime * result + ((roomId == null) ? 0 : roomId.hashCode()); return result; }
Javaでは、同値の判定をするオブジェクト(値オブジェクト)を実装する場合は、equalsとhashCodeをオーバーライドして同値判定の実装をするのが定石です。
IDEにIntelliJ IDEAを使っていたので、試しに IntelliJのコード生成機能で equalsとhashCodeメソッドの実装を生成したところ、次のようなコードとなりました。
@Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; ReservableRoomId that = (ReservableRoomId) o; return Objects.equals(roomId, that.roomId) && Objects.equals(reservedDate, that.reservedDate); }
@Override public int hashCode() { return Objects.hash(roomId, reservedDate); }
java.util.Objectsクラス(JDK 7から導入されたユーティリティクラス)の equals(Object, Object)メソッドとhash(Object...)メソッドを使って、とっても簡潔な実装となっています。
読書会参加メンバーでEclipseを使用している人に、同様に equalsとhashCodeのメソッドをコード生成してもらったところ、java.util.Objects を使用せず、書籍と同じような長いコードが生成されていました。
ということで、IntelliJ IDEAが コード生成機能をきちんと洗練していることが分かりました。
schema.sql
Spring Boot で、application.propertiesに、spring.sql.init.mode=always と指定すると、Spring Bootアプリケーションを起動したときに、src/main/resources/ ディレクトリの下にある schema.sql ファイルと data.sql ファイルを実行します。
schema.sqlには、DDL文を、data.sql には初期データをインサートするSQLを記述します。 書籍では、schema.sql の中に、外部参照の制約をCONSTRAINTで定義しますが、CONSTRAINTに、ハッシュのような長い文字列が付いています。
例
ALTER TABLE reservable_room ADD CONSTRAINT FK_f4wnx2qj0d59s9tl1q5800fw7 FOREIGN KEY (room_id) REFERENCES meeting_room;
これはどうやら Hibernate のスキーマ生成ツール hbm2ddl がJPAのアノテーション付きエンティティからSQLのDDL文を生成しているもののようです。
シンプルに外部参照を指定するなら、CREATE TABLEの中に記述することもできます。
CREATE TABLE reservable_room ( room_id INT4 NOT NULL REFERENCES meeting_room (room_id), :
schema.sql と data.sql に記載のSQL文は、1文ずつJDBC経由でデータベースに投入されているようです。
読書会の冒頭、アフターでの話題
パッケージ構成(ディレクトリ構成)
Spring のパッケージ構成は、書籍のサンプル・チュートリアルのように レイヤーの観点でまずパッケージを構成し、それぞれの中で必要に応じて機能ごとのサブパッケージを構成する方法(package by layer)と、アプリケーションの業務(機能)の観点でパッケージを構成、それぞれの中で必要に応じてレイヤーごとのサブパッケージを構成する方法(package by feature)とがよく適用されています。
src/main/java/com/torutk/hello +- controller/ | +- login/ | +- search/ | +- edit/ +- model/ +- service/ +- repository/
レイヤー観点の分割が上位のパッケージにあると、一つのアプリケーションを構成するソースファイルがかなり広範囲に散らばるので、まとまりという点では機能観点での分割が良さそうに思いました。
MavenはXMLで設定を書かなくても良い
pom.xmlは、XMLなので人の目には少し厳しい(タグの記述がコンテンツよりも目立つ・多い)ですが、最近(しばらく前から?)はXMLではなくYAML形式のpom.yml で記述できるようです。
Maven使っている読書会参加者も知らなかったようです。 Gradleを使っているので、どれだけ利便性が向上するかは分かりませんが、反応はよさそうでした。
Redmineのバージョンアップ(6.0→6.1)作業メモ
はじめに
Linuxサーバー(Rocky Linux 8)上で、Unicornアプリケーション(Rack)サーバーとNginx Webサーバーを用いた環境でRedmineを稼働しています。
この環境での Redmineバージョンアップ手順と問題対処などをメモしておきます。
Redmineのバージョンは、セマンティックバージョンに基づいて3桁の数値で指定されます。
バージョン番号の付与 - ソフトウェアエンジニアリング - Torutk
バージョンアップの際、どの桁の数値が上がるかで作業が変わります。今回は、稼働中のRedmine 6.0.2を先月リリースされた Redmine 6.1.0にバージョンアップするので、2桁目のマイナーバージョンが上がるマイナーバージョンアップとなります。
アップデート作業
Rubyバージョンの更新
Redmine 6.1のリリース情報から、Rubyの対応バージョンを確認します。Ruby 3.2、3.3および3.4に対応とあります。現在稼働しているサーバーのRubyバージョンを調べると
~$ ruby -v ruby 3.1.7p261 (2025-03-26 revision 0a3704f218) [x86_64-linux]
残念ながら、対応バージョンから外れていました。というかRuby 3.1自体が 2025年3月でEOL(サポート終了)となっていました。
Rocky Linux 8で対応しているRubyのバージョンを確認すると、次のとおり Ruby 3.3を入れることが可能です。
~$ dnf module list ruby Name Stream Profiles Summary ruby 2.5 [d] common [d] An interpreter of object-oriented scripting language ruby 2.6 common [d] An interpreter of object-oriented scripting language ruby 2.7 common [d] An interpreter of object-oriented scripting language ruby 3.0 common [d] An interpreter of object-oriented scripting language ruby 3.1 [e] common [d] An interpreter of object-oriented scripting language ruby 3.3 common [d] An interpreter of object-oriented scripting language ヒント: [d]efault, [e]nabled, [x]disabled, [i]nstalled
Rubyバージョンを変更すると、Rubyのgemパッケージ群も更新が必要になります。
まず Rubyの更新を実施します。
~$ sudo dnf module reset ruby -y : ~$ sudo dnf module enable ruby:3.3 -y : ~$ sudo dnf install ruby :
rubyに関係するOSパッケージの更新を実施します。
~$ sudo dnf update
Redmineの更新
更新前のRedmine 6.0は、git cloneにより /var/lib/redmine-6.0-stable に展開しています。Redmineの更新方法としては、cloneしたローカルディレクトリ上でブランチを6.1に切り替えるか、あらたに ブランチ6.1をgit cloneするかの方法があります。 今回は、Rubyも更新しているので、新たにgit cloneする方法とします。
~$ sudo git clone -b 6.1-stable https://github.com/redmine/redmine.git /var/lib/redmine-6.1-stable : ~$ sudo chown -R redmine:redmine /var/lib/redmine-6.1-stable/
新たにcloneしてきたので、設定ファイルをコピーしてきます。
redmine-6.1-stable$ cp ../redmine-6.0-stable/config/database.yml config/ redmine-6.1-stable$ cp ../redmine-6.0-stable/config/configuration.yml config/ redmine-6.1-stable$ cp ../redmine-6.0-stable/config.ru . redmine-6.1-stable$ cp ../redmine-6.0-stable/config/unicorn.rb config/
- config/routes.rb は、後で修正
Redmineが必要とするgem群をインストールします。
redmine-6.1-stable$ bundle config set --local path vendor/bundler redmine-6.1-stable$ bundle config set --local without 'development test' redmine-6.1-stable$ bundle config set --local force_ruby_platform true
- config set で、/var/lib/redmine-6.1-stable/.bundle/config に設定が書かれます。
- Nokogiri gemのインストールはデフォルトでglibc 2.29へのリンクを含みますが、Locky 8はglibc 2.28のためリンクエラーとなります。そこでgem インストール時にビルドを行うよう設定しています。
gemパッケージのインストールにネイティブビルドをするようになったら、commonmarker gemのインストールがエラーとなってしまいました。clang関係パッケージが必要となっています。
~$ sudo dnf install clang :
redmine-6.1-stable$ bundle install :
セッションデータ用クッキーの暗号化キー生成
redmine-6.1-stable$ bundle exec rails generate_secret_token
稼働中のRedmineを停止
~$ sudo systemctl stop redmine-unicorn
データベーススキーマの更新
redmine-6.1-stable$ bundle exec rails db:migrate RAILS_ENV=production
Unicornインストール
/var/lib/redmine-6.1-stable/Gemfile.local を作成
gem "unicorn" gem "unicorn-worker-killer"
redmine-6.1-stable$ bundle update
~$ sudo ln -s /var/lib/redmine-6.1-stable /var/lib/redmine
/usr/lib/systemd/system/redmine-unicorn.serviceの修正
- WorkingDirectory=/var/lib/redmine-6.0-stable + WorkingDirectory=/var/lib/redmine-6.1-stable - PIDFile=/var/lib/redmine-6.0-stable/tmp/pids/unicorn.pid + PIDFile=/var/lib/redmine-6.1-stable/tmp/pids/unicorn.pid
~$ sudo systemctl daemon-reload
添付ファイルの格納ディレクトリの移動
redmine-6.1-stable$ rm -rf file redmine-6.1-stable$ mv ../redmine-6.0-stable/files/ .
プラグインのインストール
redmine-6.1-stable$ cd plugins/ plugins$ git clone https://github.com/agileware-jp/redmine_banner.git : plugins$ git clone https://github.com/agileware-jp/redmine_issue_templates.git : plugins$ git clone https://github.com/process91/redmine_latex_mathjax.git : plugins$ git clone https://github.com/haru/redmine_theme_changer.git : plugins$ git clone https://github.com/haru/redmine_wiki_extensions : plugins$ git clone https://github.com/tkusukawa/redmine_wiki_lists.git : plugins$ git clone https://github.com/onozaty/redmine-view-customize.git : plugins$ git clone https://github.com/torutk/redmine_cozy_wiki_macros.git : plugins$ git clone https://github.com/torutk/redmine_glossary.git :
必要なgemをインストール
redmine-6.1-stable$ bundle update :
データベースのマイグレーション実施
redmine-6.1-stable$ bundle exec rails redmine:plugins:migrate RAILS_ENV=production
テーマのインストール
redmine-6.1-stable$ git clone https://github.com/farend/redmine_theme_farend_bleuclair.git themes/bleuclair
デフォルトのページ設定
config/routes.rb
- root :to => 'welcome#index' - root :to => 'welcome#index', :as => 'home' + root :to => 'wiki#show', :project_id => 'swe', :as => 'home'
Java SE 24/JDK 24のリリース
JDK 24のリリースと耐量子暗号
2025-03-18に、JDK 24がリリースされました。半年毎の定期バージョンアップで、非LTSです。 JDK 24
ざっと新機能を眺めてみると、Quantum-Resistant で始まる機能が2つほど正式採用されていました。
- Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism (JEP 496)
- Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm (JEP 497)
なんだろうなと思いつつ、JEPのサマリを読んでもピンときませんでした。そんな時、日経NETWORK 2025年3月号の包装を開き、ペラペラ読んでいたら、特集記事「耐量子暗号は正解か 暗号の2030年問題」に、RSA-2048の移行先として耐量子暗号が候補に上がっており、JEPのサマリに登場した略語 ML-KEM、ML-DSA が出てきました。
記事を要約すると
現在の暗号方式であるRSAやECCは暗号方式として素因数分解や楕円上の離散対数に基づいpており、今後量子コンピュータの性能向上で解読されることが予想されています。そこで、量子コンピュータでも解読が難しい耐量子暗号として、格子暗号、符号暗号、多変数多項式暗号に基づく暗号方式の標準化をNISTが進めており、2024年8月に鍵交換・データ暗号化に使うML-KEM、デジタル署名に使うML-DSA、SLH-DSAの3つが標準化されました。残るデジタル署名のFN-DSAはまだ標準化が公開されていません。
ここで登場する ML-KEMがJEP 496、ML-DSAがJEP 497でJDK 24に取り入れられたということです。
ただ、記事では、耐量子暗号の安全性の検証に十分時間がかけられておらず、今後脆弱性が見つかる可能性も指摘されていました。
Java読書会「Spring徹底入門 第2版」を読む会(第1回)を終えて
Java読書会BOF主催「Spring徹底入門 第2版」を読む会(第1回)が10月20日(日)に開催されました。
前回の書籍(基礎からのサーブレット/JSP入門 第5版)は、参加人数が2-3人と少し寂しい読書会でした。今回は7人の参加で開催となり、前回の書籍の読書会に比べると賑わった会となりました。
Springの書籍
今回の課題図書となった「Spring徹底入門 第2版」(2024年5月刊)のほかに、類書で「プロになるためのSpring入門 ――ゼロからの開発力養成講座:書籍案内|技術評論社(2023年7月刊)」があります。書籍の対象とするSpring Frameworkのバージョンが、「Spring徹底入門 第2版」が5系 である一方「プロになるためのSpring入門」が6系となっています。
書籍のボリュームは、「Spring徹底入門 第2版」が752ページに対して「プロになるためのSpring入門」が384ページとほぼ倍のボリュームとなっています。
目次構成を見ると、「Spring徹底入門 第2版」は、Springの概要紹介の薄い1章の後は、2章でDIとAOPの詳細な説明が開始され、頭から読んで手を動かしながら徐々に詳しく解説していくる体裁ではなく、リファレンス的な構成になっています。開発環境についてはAの付録で記載、Hello World的なサンプルは13章の Spring Bootの章で初めて出てきます。 「プロになるためのSpring入門」は、第1部基本編と第2部詳細編と2部構成で徐々に詳しく解説していくスタイルのようです。
入門としての読みやすさは「プロになるためのSpring入門」で、独学でも読めそうです。一方、読書会向き(議論が活発になる書籍)ということではSpring徹底入門なのかなとの感触です。入門本で700ページ越えもサイズが強烈です。
PDFの入手
書籍サイトでは電子書籍の購入で、一見PDF版が見当たらず、KindleやKobo、Hontoに誘導されるように見えますが、PDF版を翔泳社から購入可能です。今回、電子書籍購入して参加の方の多くが、PDF版がないと思いKindle版を購入したと言っていました。次の図の操作でPDF版の購入に辿れました。

Spring Boot開発環境
書籍で解説されるコード断片を実行しようとする場合、DIコンテナを含めて各フレームワーク・ライブラリが動く環境が必要です。簡単にSpringアプリケーションを動かすのがSpring Bootの機能なので、まずはSpring BootでSpringアプリケーションを作って動かせるようにします。
書籍では、A.付録において、Spring Frameworkを使うアプリケーションの開発環境として、EclipseベースのSTS(Spring Tool Suite)の準備が説明されています。
Spring Bootの開発では、WebサービスのSpring Initializr へアクセスし、設定を入力するとプロジェクトの雛形がダウンロードできるので、これを展開してIDEに読ませるという流れになります。設定ではビルドツールにMavenかGradleを選択できます。
IntelliJ IDEAの場合、有償のUltimate版なら Spring Initializrにアクセスしなくてもプロジェクトの作成からSpring Bootを選択して雛形を生成できます。と言っても、プロジェクトの作成では裏でSpring Initializrをアクセスしているようです。無償のCommunity版の場合は、Spring Initializrにアクセスして生成した雛形を読み込んで使用する方法となります。
Spring Bootを使ってビルドしたアプリケーション(JAR形式)は、Webサーバーが組み込まれるので、JARファイルを実行するだけでWebサーバーを用意しなくてもWebブラウザからアクセスが可能になります。デフォルトではembedded TomcatらしきクラスファイルがJARに含まれていました。
IntelliJ IDEA(Ultimate版)でSpring Bootプロジェクト生成
新規プロジェクトを生成します(File > New > Project)

プロジェクト名、言語、ビルドツール、パッケージ名などを選択・入力します。

Dependencies で、Spring Webを選択します。これを選択することで、SpringのWeb機能の基本的な振る舞いを利用できるようになります。ブラウザにHelloメッセージを表示する最初のプログラムはこのライブラリを使用します。

アプリケーションのmainクラス(エントリーポイント)とテストクラスの雛形が生成されました。 生成されたmainクラスを実行すると、Webサーバー機能が動作し、デフォルトではデフォルトでは 8080ポートで待ち受けます。Webブラウザからlocalhost:8080に接続すると次のエラーが発生します。これは、ルート/にマッピングされる処理が未定義のため 404エラーとなっている場合のメッセージです。
Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Mon Oct 28 00:00:55 JST 2024 There was an unexpected error (type=Not Found, status=404).
Hello World! とメッセージを表示するWebアプリケーションとするために、生成されたmainクラスに@RestControllerアノテーションを付与し、HTTPのGETメソッドでルート/を指定された際にメッセージを返却するメソッドを@GetMappingアノテーションを付与して定義します。
package com.torutk.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class DemoApplication { @GetMapping("/") String hello() { return "Hello World!"; } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
Hello World的なWebアプリとして単一クラスで完結させるのに、REST APIを扱う@RestControllerを使用しました。 コントローラのメソッドにREST APIのメソッド(GET)をマッピングし、メソッドの戻り値をAPIの戻り値にラップします。戻り値の型をStringとしているので単純な文字列が返却されますが、通常はリソースクラスを定義して返却します。
通常のWebアプリケーション用の@Controllerは、別途Viewに相当する仕組みを用意するか、@ResponseBodyを使うなどひと手間かかります。
史跡巡り 桶狭間合戦場・大高城・鷲津砦・丸根砦
先日、遅めの夏休みを取って、名古屋方面に一人旅をしてきました。 織田信長の足跡をたどって、初日は桶狭間合戦場と、大高城、鷲津砦、丸根砦の跡を巡りました。
地図に、大高城と鷲津砦、丸根砦、そして桶狭間合戦場と伝えられる場所をマークしました。また当時は大高城付近まで海となっており、地図で平地(緑色)の大半は海と考えられます。
出展:国土地理院ウェブサイト デジタル標高地形図 濃尾平野周辺をもとに、城・砦跡、合戦場をマークして記載
大高城は織田方から今川方のものになっており、鷲津・丸根の砦は大高城に対抗するため織田方が築いた砦です。桶狭間合戦の日に鷲津砦・丸根砦は今川方の攻撃を受け落城、今川義元は本隊を率いて沓掛城から大高城へ入る途中、桶狭間付近で織田信長の奇襲を受けて受けて打ち取られ、今川方は撤退していきました。
桶狭間合戦場の場所は、実際には特定されておらず、上述地図に記載した場所のほかに、旧東海道沿いの場所があるようです。



- 鷲津砦跡から徒歩10分弱、尾根伝いに歩くと至ります。

- 鷲津砦跡から徒歩20分、砦と違ってそこそこの大きさです。
経路
今回は、名古屋駅から名鉄で有松駅に向かい、有松駅からバスで桶狭間寺前で下車、NPO法人が運営する桶狭間古戦場観光案内所に寄ってから桶狭間公園とそこから数十mほどにある今川義元本陣跡(住宅の前に看板だけある)、そこから有松駅方面に徒歩で向かい、旧東海道沿いの有松伝統的建造物群保存地区を見ながら有松駅に着きました。
名鉄有松駅からバスでJR大高駅に向かい、大高駅のすぐそばにある鷲津砦跡から丸根砦跡を回り、そこから大高城へ歩いて向かいました。
Webまわりの技術知識の獲得のための書籍購入
Java読書会BOFで「基礎からのサーブレット/JSP 第5版」を読みすすめていると、Webアプリケーションの技術知識として増やしたいことがいくつかでてきました。
- Webページの見栄えをよくするには、HTMLに加えてCSS(Cascading Style Sheets)が必要
- Webページに動きを伴わせるには、JavaScriptが必要か、Javaだけでもできるかを知りたい
- HTTP/2やHTTP/3について知識をえておきたい
そこで、2、3冊書籍を買って読み始めました。
まずはHTMLとCSSの本から選んだのが「1冊ですべて身につくHTML&CSSとWebデザイン入門講座」(SBクリエイティブ刊 2024年3月)
JavaScriptをブラウザ上でどのように使うのか、フロントエンド全般に書かれた「フロントエンドの知識地図 ~ 一冊でHTML/CSS/JavaScriptの開発技術が学べる本」(技術評論社刊 2023年11月)
HTTP全般について、HTTP/2、HTTP/3も解説のある「Real World HTTP 第3版」(オライリージャパン刊、2024年4月)
