🎯 本記事の目的
Struts2はサーバーサイドMVC型の代表的なJavaフレームワークですが、HTML画面を返すだけでなく、JSON形式のレスポンスも扱えます。本記事では以下の内容を解説します:
-
JSONを返すためのStruts2の設定方法
-
実装例(ユーザー情報返却API)
-
JSON出力のカスタマイズ方法
-
セキュリティ面の注意点(CORS, CSRFなど)
🔸 1. なぜStruts2でJSON返却?
Struts2はもともとHTMLベースの画面遷移を前提としていますが、最近のアプリケーションでは以下のようなJSON連携のニーズ があります。
-
✅ 画面の一部だけを非同期更新したい(AJAX)
-
✅ モバイルアプリからJSON APIを呼び出したい
-
✅ SPA(Single Page Application)でバックエンドAPIを分離したい
このような場面では、Struts2でHTMLビューではなくJSONデータを返す仕組みを使うことで、柔軟な連携が可能になります。
🔧 2. Struts2でJSONレスポンスを返す構成
📌 必須ライブラリ(struts2-json-plugin)
Struts2でJSONを返すには、以下のjarをプロジェクトに追加します。
<!-- pom.xml (Mavenの場合) -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.5.31</version> <!-- プロジェクトに合わせて調整 -->
</dependency>
補足:
struts2-json-plugin
が提供するResultタイプ "json" を利用することで、ActionクラスのプロパティをそのままJSONとして返せます
🛠 struts.xml の設定
<package name="json-api" namespace="/api" extends="json-default">
<action name="getUserList" class="com.example.action.GetUserListAction">
<result type="json" />
</action>
</package>
ポイント:
-
extends="json-default"
にすることでJSON機能が有効化されます。 -
<result type="json" />
を設定すると、戻り値が JSON になります。
🧪 3. 実装例:ユーザー情報をJSONで返す
🎯 要件
以下のようなJSONを返すエンドポイント /api/getUserList.action
を作成します。
{
"users": [
{ "id": 1, "username": "alice" },
{ "id": 2, "username": "bob" }
]
}
🧱 Actionクラスの実装
package com.example.action;
import com.opensymphony.xwork2.ActionSupport;
import java.util.ArrayList;
import java.util.List;
public class GetUserListAction extends ActionSupport {
private List<UserDto> users;
@Override
public String execute() {
users = new ArrayList<>();
users.add(new UserDto(1, "alice"));
users.add(new UserDto(2, "bob"));
return SUCCESS;
}
public List<UserDto> getUsers() {
return users;
}
public static class UserDto {
private int id;
private String username;
public UserDto(int id, String username) {
this.id = id;
this.username = username;
}
public int getId() { return id; }
public String getUsername() { return username; }
}
}
💡 解説
-
getUsers()
というgetter
を持つことで、自動的にusers
プロパティがJSONに変換されます。 -
UserDto
は内部クラスでもOKですが、実運用では独立したDTOクラスが望ましいです。
🔍 4. JSON出力のカスタマイズ方法
Struts2のJSON出力はかなり柔軟にカスタマイズできます。
✅ 除外プロパティを指定(例えばpasswordなど)
<result type="json">
<param name="excludeProperties">users\[\d+\]\.password</param>
</result>
✅ ルートプロパティのみ返す(root
指定)
<result type="json">
<param name="root">users</param>
</result>
結果例(users
の配列のみをルートとして返す):
[
{ "id": 1, "username": "alice" },
{ "id": 2, "username": "bob" }
]
🔐 5. セキュリティ上の注意点(REST連携)
🔸 CORS(クロスオリジン)制御
他ドメインからアクセスされる場合、レスポンスに以下のヘッダを設定する必要があります:
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("Access-Control-Allow-Origin", "*");
※ 実運用では * は避けて、信頼ドメインだけ許可しましょう。
🔸 CSRF対策(JSONリクエストでも重要)
-
JSON APIでもCSRFトークンの検証が必要です。
-
POSTリクエストを扱う場合は、セッションやヘッダでトークンを送信・検証する実装が求められます。
-
参考:
TokenInterceptor
の利用や、X-CSRF-TOKEN
ヘッダのチェックなど。
🔸 認証連携(APIへのログインチェック)
JSON返却Actionでも、通常の画面遷移と同様にログインセッションの検証が必要です。
Interceptor で session.get("loginUser") == null
をチェックするなど。
🧾 おわりに:Struts2 × REST設計も十分可能!
Struts2は古典的なMVCフレームワークではありますが、json-defaul
t パッケージと Result設定
を使うことで、REST風のJSON API
構築も可能です。
-
フロントエンドとの非同期連携
-
スマホアプリ向けのデータ提供
-
JavaScriptによる動的UI制御(SPA)
といった現代のニーズにも柔軟に対応できます。
✅ まとめ:Struts2 JSON連携のチェックリスト
項目 | 内容 |
---|---|
ライブラリ |
struts2-json-plugin.jar を追加 |
パッケージ |
extends="json-default" にする |
Result設定 | <result type="json" /> |
DTOクラス | Getterを備えたプロパティ設計 |
セキュリティ | CORS, CSRF, 認証の確認 |
🧭 関連記事(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.10 | Struts2の「OGNL」ってなに?しくみと使い方をやさしく解説 | 式言語OGNL解説 |
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.22 | 本番環境構成とセキュリティ設計(Apache+Tomcat+Struts2連携) | 外部公開 |