1.

Struts1 の ActionMapping とは? <action> 定義・ActionForward・findForward の使い方

編集
この記事の要点
  • ActionMappingStruts1struts-config.xml 1 件分のメタ情報を保持するクラス
  • がリクエスト URL とアクションクラスの対応を決める
  • execute() 内で mapping.findForward("success") を呼ぶと が解決される
  • 入力検証失敗時は input 属性で指定した JSP に戻る(ActionForm.validate()ActionErrors を返すと自動分岐)
  • は全アクション共通の遷移先、modules で機能単位に struts-config-xxx.xml を分割可能
  • Struts1 は 2013 年 EOL。新規開発は Spring MVC / Spring Boot 推奨

ActionMapping とは

org.apache.struts.action.ActionMapping は Struts1 のコアクラスで、struts-config.xml に書かれた 要素 1 件分の情報を保持します。フレームワークはリクエスト URL に対応する ActionMapping を見つけ、それを Action#execute() の第 1 引数として渡します。

struts-config.xml の典型例





  
  
    
  

  
  
    
    
  

  
  
    
      
      
    
  

属性の意味

属性意味備考
pathリクエスト URL の論理名(拡張子前)/login なら /login.do が来る
type実行する Action クラス FQDN必須
name使用する ActionForm の論理名form-beans 内の name と対応
scopeフォームのスコープrequest / session
input検証失敗時の戻り先 JSPvalidate="true" 時に必須
validateフォーム検証を行うかtruevalidate() が呼ばれる
parameterサブメソッド指定(DispatchAction 用)method

Action#execute() での使い方

package com.example.action;

import org.apache.struts.action.*;
import javax.servlet.http.*;

public class LoginAction extends Action {

    @Override
    public ActionForward execute(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {

        LoginForm lf = (LoginForm) form;

        // ビジネスロジック
        boolean ok = AuthService.login(lf.getUserId(), lf.getPassword());

        if (ok) {
            //  へ
            return mapping.findForward("success");
        } else {
            // ActionErrors を積んで戻る
            ActionMessages errors = new ActionMessages();
            errors.add(ActionMessages.GLOBAL_MESSAGE,
                       new ActionMessage("error.login.failed"));
            saveErrors(request, errors);

            //  へ
            return mapping.findForward("failure");
        }
    }
}

findForward() の動作順

mapping.findForward("success") は次の順で ActionForward を探します:

  1. その 配下の
  2. 見つからなければ 配下の
  3. それも無ければ null を返す(白画面 / NPE の元)

入力検証失敗時のフロー(input 属性)

validate="true" の場合、ActionForm#validate()execute() より先に呼ばれます。ActionErrors が空でなければ execute() はスキップされ、input 属性の JSP に戻ります:

public class LoginForm extends ActionForm {
    private String userId;
    private String password;

    @Override
    public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();
        if (userId == null || userId.isEmpty()) {
            errors.add("userId", new ActionMessage("error.userId.required"));
        }
        if (password == null || password.length() < 8) {
            errors.add("password", new ActionMessage("error.password.length"));
        }
        return errors;  // 空でなければ input 属性の JSP へ
    }
    // getter/setter ...
}

modules による分割

大規模アプリでは機能単位に config を分けられます:



  action
  org.apache.struts.action.ActionServlet
  
    config
    /WEB-INF/struts-config.xml
  
  
    config/order
    /WEB-INF/struts-config-order.xml
  
  
    config/admin
    /WEB-INF/struts-config-admin.xml
  

URL は /order/list.do, /admin/users.do のように module 名が prefix になります。

Spring MVC への移行

Struts1 は Apache 公式 2013 年 12 月 EOL。新規開発はもちろん、既存も計画的に Spring MVC / Spring Boot に移行すべきです。対応関係:

Struts1Spring MVC
@RequestMapping("/login")
ActionForm@ModelAttribute の DTO
ActionForwardreturn "home" (View 名)
findForward("success")同上 / ModelAndView
validate()@Valid + Bean Validation
struts-config.xmlJava Config / @Configuration

FAQ

Q: findForward() が null を返す
A: のスペルミスが多い。 にも無いか確認。

Q: input 属性が無いと?
A: validate="true" で検証失敗時に java.lang.IllegalStateException: No input attributeinput は必須。

Q: redirect="true" の意味
A: RequestDispatcher.forward() ではなく sendRedirect() を使う。request 属性は失われるので注意。

編集
Post Share
子ページ
  1. getInputForward
同階層のページ

同階層のページはありません