【Struts】初めてのStruts学習【概要・超基礎編】

# はじめに
Struts未経験の状態でStrutsメインのプロジェクトに携わることになった私が、
１からStrutsを学習したのでその内容を簡単にまとめてみました。
基本的にSpringにしか縁が無かったのですが（大半がそうかも？）意外とまだStrutsがベースのプロジェクトもあると思うので、
「Strutsってなーに？」「どんなFWなの～」
みたいな方々に向け、実用的な部分も含め学習のはじめの一歩となるような記事になれば嬉しいです。

:::note info
Strutsの基本的な概要や構成要素についてを主に説明しています。Strutsの環境構築などは触れていません:pray_tone1:
:::

# Strutsについて
「Strutsとは」で検索すると、だいたいどのページにも
**MVCモデルを採用した、WEBアプリケーションを作成するためのJavaのフレームワーク**
と書いてあると思います。
Strutsの意味としては文字通りなんですが、私はこの日本語だけでは理解できたようで理解できなかったのでもう少し掘り下げてみます。

## 1-1．MVCモデル（ざっくり版）
Strutsは以下の主要な3つの要素で構成されています。
- Model…プログラムのメイン処理が記述されているところ
- View…最終的に画面に表示する機能
- Contoroller…ModelとControllerそれぞれに指示出しをするところ

私がイメージする各役割担当の図を表してみました。
![スクリーンショット 2024-12-15 222611.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620421/52f93d5c-a212-3a83-4119-526d6c57ba44.png)

（※MVCに関してはStrutsに限らずさまざまなフレームワークで使用されているアーキテクチャなのでここではざっくり）
上の図をStruts的に解釈するとこんな感じ
| 構成要素 | 役割 |
| ---- | ---- |
| Model | ビジネスロジックやデータ処理を担当する。JavaBeansやデータベースとの連携が含まれる。 |
| View | ユーザーインターフェース部分（HTML、JSPなど）。データの表示を担当する。|
| Controller | リクエストを処理し、ModelとViewの連携を担当する。StrutsではActionServletがこれに該当する。 |

### 1-2．Strutsの主要コンポーネント
MVCモデルがベースになっているのは良いとして、それぞれの役割を持つM,V,C君たちはそれぞれ何をしているんだい？というのをもっと実践的にサンプルソースも出して説明していきます。
#### (1) ActionServlet
Strutsアプリケーション全体のエントリーポイントの役目を持ち、MVCの「Controller」としての役割を果たします。
上の図だと、「サイトにログインしたいよ～」のようなリクエストを受け取ったら、そのリクエストを元に適切な処理を実行します。（クライアントからのHTTPリクエストを受け取り、Actionクラスのexecuteメソッドの実行、適切な遷移先画面を返却、など）

#### (2) struts-config.xml
※Struts学習の要かも？
Strutsの設定を管理するXMLファイルでAction名に紐付いた遷移先を設定するファイルです。
(1)のActionServletでは、この`struts-config.xml`で定義された設定を基に、どのActionクラスを実行するか判断します。

基本的にこの`struts-config.xml`に「どの画面に遷移するか」「どの処理が実行されるか」の設定が記載してあるのでこの`struts-config.xml`が攻略できればだいたい処理の流れが見えてきます。

記載されている内容のサンプルです。
- URLパターンとActionクラスのマッピング
- フォーム（ActionForm）の定義
- フォワード先のJSPなどのビューの定義　　　　　etc...
```struts-config.xml
<struts-config>
  <form-beans>
    <form-bean name="loginForm" type="com.example.forms.LoginForm" />
  </form-beans>
  
  <action-mappings>
    <action path="/login" 
            type="com.example.actions.LoginAction"
            name="loginForm"
            scope="request"
            input="/login.jsp">
      <forward name="success" path="/home.jsp" />
      <forward name="failure" path="/error.jsp" />
    </action>
  </action-mappings>
</struts-config>
```

上記のXMLを読み解くと、下記のような処理の流れが分かります:thumbsup_tone1:

1. クライアントが`/login`にリクエストを送信
2. `struts-config.xml`で、リクエストパス/loginに対応する<action>要素を探す
3. `type="com.example.actions.LoginAction"` で指定されたクラスが実行される
4. `name="loginForm"` に基づき、`com.example.forms.LoginForm`クラスのインスタンスが作成され、リクエストデータがマッピングされる
5. `LoginAction`クラスの`execute`メソッドが呼ばれる（実行時に、4.の`ActionForm`のデータが渡されビジネスロジックが処理される）
6. `LoginAction`クラスの`execute`メソッドで処理結果に応じて、
successまたはfailureのどちらかの名前でフォワードが選択されます。
・成功時: `/home.jsp`
・失敗時: `/error.jsp`


#### (3) Actionクラス
リクエストに応じたビジネスロジックを実行し、実行結果に応じて適切なActionForwardオブジェクトを返し、次に表示するビュー（JSPなど）を決定します。
MVCの「Model」の役割を担っており、以下のような特徴が挙げられます。
- Actionクラスを継承する
Strutsの`org.apache.struts.action.Action`クラスを継承して実装する
- メインメソッドであるexecute()をオーバーライドしてリクエスト処理を行う

```LoginAction.java
public class LoginAction extends Action {
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request, HttpServletResponse response) throws Exception {
        // フォームデータを取得
        LoginForm loginForm = (LoginForm) form;
        String username = loginForm.getUsername();
        String password = loginForm.getPassword();

        // 実際の処理部を呼び出して認証処理を実行
        LoginService loginService = new LoginService();
        boolean isAuthenticated = loginService.authenticate(username, password);

        // 結果に応じてビューを選択（findForwardメソッドを使用）
        if (isAuthenticated) {
            return mapping.findForward("success");
        } else {
            return mapping.findForward("failure");
        }
    }
}
```

#### (4) ActionForm
HTMLフォームの入力データを格納するJavaBean。リクエストデータを受け取り、Actionクラスに渡します。
ここでは省略しますが、フォームデータをバリデーションするためのメソッドを提供することも可能です。
```LoginForm.java
public class LoginForm extends ActionForm {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
```

#### (5) JSP
MVCの「View」の役割を担っており、Actionクラスの結果に応じて画面に表示する内容を返却します。

```jsp:login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<!DOCTYPE html>
<html>
<head>
    <title>ログイン</title>
</head>
<body>
    <html:form action="/login">
        ユーザー名: <html:text property="username" /><br/>
        パスワード: <html:password property="password" /><br/>
        <html:submit value="ログイン" />
    </html:form>
</body>
</html>
```
<br>


※下記２つは主要コンポーネントというわけでは無いけど、、、
#### (6) タグライブラリ（Struts Taglib）
JSPでのフォーム操作やデータ表示を簡潔に記述するためのカスタムタグ集。
代表的なタグ:
`<html:form>`: フォーム作成。
`<html:text>`: テキスト入力フィールド。
`<html:submit>`: サブミットボタン。

#### (7) Message Resources
エラーメッセージや通知メッセージを外部化するためのリソースファイルです。

```messages.properties
login.error=ユーザー名またはパスワードが間違っています。
login.success=ログイン成功！
```

## 2-1．Strutsの全体的な流れ
Strutsの主要構成要素について長々と説明してきましたが、リクエストを受け取ってからレスポンスを生成するまでの全体的な流れをまとめます。
**1.リクエスト受信**
　クライアント（ブラウザ）がリクエストを送信し、[1-2(1)](#1-actionservlet)`ActionServlet`が受け取る。
**2.ルーティング**
 　[1-2(2)](#2-struts-configxml)`struts-config.xml`を参照し、リクエストを対応する[1-2(3)](#3-actionクラス)Actionクラスに渡す。
**3.ビジネスロジック処理**
　[1-2(4)](#4-actionform)`ActionForm`のデータが渡され、Actionクラスがビジネスロジックを実行する。
**4.結果のフォワード**
　ビジネスロジックの結果に応じて、指定された[1-2(5)](#5-jsp)JSP（View）にフォワードする。
**5.レスポンス生成:**
　JSPがHTMLを生成し、クライアントに返す。

 # さいごに
 Strutsについての大まかな概要と主要構成要素をまとめてみました。
 本当はもっともっと説明すべきことがあると思うんですけど、、、とりあえず概要のイメージ掴むとっかかりくらいに思ってもらえたら嬉しいですね。
 最初に全体像のイメージを頭に入れておけばすんなりと理解できるところも多かったですが、まだまだ細かい記述方法や、実装方法には四苦八苦していたりするので実装時に困った内容などもいつかできれば:frowning2: