式言語OGNL解説:Struts2の中核をなす「OGNL」をやさしく丁寧に解説し、実務での使い方まで掘り下げる
✅ 1. はじめに:OGNLってそもそも何?
OGNL(Object-Graph Navigation Language) は、Javaオブジェクトのプロパティにアクセスしたり、メソッドを呼び出したりできる「式言語」です。
Struts2では、JSP内で変数やプロパティを記述する際にこのOGNLが使われています。
例えば、JSPの以下のような記述:
<s:property value="user.name" />
このような記述は、Struts2のタグライブラリがOGNLを使って user.getName() を評価しているということになります。
✅ 2. なぜStruts2でOGNLが使われているのか?
Struts2はActionクラスを中心とするMVCアーキテクチャですが、View(JSP)とModel/Action間のバインディングやデータアクセスを簡素にするため、OGNLを導入しています。
主なメリットは以下の通りです:
-
複雑なオブジェクト構造に対するプロパティアクセスが簡単
-
値の設定(setter)や取得(getter)両方に対応
-
コレクションや条件式、メソッド呼び出しも可能
✅ 3. OGNLの基本文法と構文
| OGNL式 | 説明 |
|---|---|
user.name |
getUser().getName() に相当 |
user.age > 20 |
条件式の評価も可能 |
userList[0].name |
リストの要素にアクセス |
#session.userId |
session スコープからの取得 |
myMap['key'] |
マップへのアクセス |
'Hello ' + user.name |
式による文字列結合 |
✅ 4. 実際のJSPにおけるOGNL使用例
<!-- user.name を画面に表示 -->
<s:property value="user.name" />
<!-- 年齢が20歳以上なら「成人」 -->
<s:if test="user.age >= 20">
成人
</s:if>
<s:else>
未成年
</s:else>
✅ 5. Actionとの連携:プロパティ参照と評価
OGNLは、Actionクラスのプロパティに直接アクセスします。
以下のようなActionがある場合:
public class UserAction extends ActionSupport {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
JSPからは以下のようにアクセスできます:
<s:property value="user.name" />
OGNLが getUser() で取得した User オブジェクトに対して getName() を呼び出す形になります。
⚠️ 6. セキュリティ上の注意点と制限
OGNLは非常に柔軟な反面、過去に多数の脆弱性(RCE:リモートコード実行) が発見されています。
そのため、以下のような対策が必要です:
-
struts.xml や struts.properties でセキュリティ制限を有効化する
-
不要なsetter/getterは定義しない
-
本番環境では devMode を絶対に無効にする
-
静的メソッドアクセスを禁止する(必要な場合は限定的に)
設定例(struts.properties)
struts.devMode=false
struts.ognl.allowStaticMethodAccess=false
🛠 7. 実務で「困るOGNL」パターンと回避策
| トラブル例 | 原因と対策 |
|---|---|
null が表示される |
オブジェクトが初期化されていない → NullチェックをJSPやAction側で行う |
#session.userId が参照できない |
スコープの変数名ミス、セッションに正しくセットされていない可能性 |
| メソッド呼び出しが失敗する |
allowStaticMethodAccess が false → 動的呼び出しが制限されている |
myList[0].name でエラーになる |
インデックス範囲外 or null要素 → listが空でないか確認 |
🎯 8. おわりに:OGNLを味方につけよう
OGNLはStruts2の柔軟性と簡潔さを支える「隠れた立役者」です。
最初は難解に感じるかもしれませんが、JSPの記述がスッキリし、保守性も向上します。
ぜひ、「見えるロジック」としてのOGNLを意識しながら実務で活用してみてください!
🔜 次回予告:Vol.11.11「ModelDriven インターフェースの使いどころと注意点」もぜひご期待ください!
🧭 関連記事(Vol.11.xxxシリーズ)
| 連番 | タイトル | 内容分類 |
|---|---|---|
| Vol.11.0 | Struts2が提供してくれる便利機能まとめ9選 | 導入&概要 |
| Vol.11.1 | 自動注入とステートレスActionの仕組み | フレームワーク内部理解 |
| Vol.11.2 | UX改善に効く!アクション層設計と入力制御の極意(プロローグ) | UX設計・アクション層総論 |
| Vol.11.2.1 | 【実践編】Struts2アクション層の役割と設計パターン(Command型 / UIアクション分離など) | アクション設計パターン |
| Vol.11.2.2 | 【UX重視】戻るボタン・キャンセル処理の設計手法と「戻り先管理」のスマート実装 | 戻り先制御とUX設計 |
| Vol.11.2.3 | 【設計ノウハウ】多画面遷移時のパラメータ受け渡し・保持戦略(セッション vs hidden vs URL) | パラメータ多重管理 |
| Vol.11.2.4 | 【実践ガイド】ユーザー操作を考慮したアクション遷移設計(リダイレクト vs フォワードの使い分け) | UX遷移設計/Result制御 |
| Vol.11.2.5 | 【トラブル防止】アクション層の共通処理とメンテナブルなBaseAction設計 | アクション共通化/保守性 |
| Vol.11.3 | Struts2の defaultStack とは?Interceptorの中身を詳しく追ってみる | Interceptor |
| Vol.11.3.2 | 🔧 Vol.11.3.2 独自Interceptorの作り方と使い所 Struts2のカスタマイズを“実践で使えるレベル”に一歩進めよう | Interceptor |
| Vol.11.4 | 入門者のための「パラメータ自動バインディング」完全理解ガイド | 自動バインディング |
| Vol.Vol.11.4.1 | 入門者のための自動バインディング実践パターン集 | 自動バインディング |
| Vol.11.5 | Struts2の構成理解が“実務レベル”へと進化する決定版 | 設定ファイル構造 |
| Vol.11.5.1 | Struts2の“画面遷移の全体像”を理解するためのマイルストーン記事 | 設定ファイル構造 |
| Vol.11.6 | ActionSupport の便利メソッドと国際化対応 | ユーティリティ / i18n |
| Vol.11.7 | validate() / input 戦略とUX設計 | 開発スタイルの違い |
| Vol.11.8 | アノテーションベースの設定 vs XML定義の比較 | 開発スタイルの違い |
| Vol.11.9 | バリデーション完全解説(XML / アノテーション) | バリデーション(※Vol.8補完) |
| Vol.11.11 | ModelDriven インターフェースの使いどころと注意点 | Model駆動開発 |
| Vol.11.12 | SessionAware と RequestAware でセッション/リクエスト管理 | セッション管理 |
| Vol.11.13 | Resultタイプ完全解説(dispatcher / redirect / stream など) | 遷移パターン理解 |
| Vol.11.14 | Vol.11.14 ValueStackの中身を理解する – 画面とActionの橋渡し役 | Action |
| Vol.11.15 | Interceptorチェーンを自作してみよう(ログ / 認証フィルタ) | Interceptor |
| Vol.11.16 | エラー処理と例外ハンドリングの実践パターン | ハンドリング設計 |
| Vol.11.17 | Struts2でファイルアップロード機能を実装する方法 | 実装系Tips |
| Vol.11.18 | 非同期通信(AJAX)とStruts2の連携方法 | フロント連携編 |
| Vol.11.19 | セキュリティ対策(CSRF, XSS, パラメータ偽装) | セキュリティ対策 |
| Vol.11.20 | 複数フォームを安全に扱う!セッション管理と動的フォームの考え方 | セッション管理 |
| Vol.11.21 | Struts2でJSONを返す!REST API連携と非同期通信の基本設計 | セッション管理 |
| Vol.11.22 | 本番環境構成とセキュリティ設計(Apache+Tomcat+Struts2連携) | 外部公開 |