intra-mart Accel Platform IM-Workflow TERASOLUNA Server Framework プログラミングガイド 第5版 2019-12-01

5.5. Controllerクラスの作成

Formクラスの内容をバインドした上で、画面(JSP)を呼び出す処理を作成します。

5.5.1. URL設計

コンテンツ定義にて画面種別ごとに異なるURLを設定できるため、画面種別(ユーザコンテンツ画面の呼び出しパターン)によってURLを分離することが可能です。また、ワークフローのシステムパラメータ imwPageTypeとして画面種別を受け取ることが可能なので、同一のURLが設定されている場合でもControllerクラスにて画面種別を判定することが可能です。

サンプルのControllerクラスでは、以下のようにjspごとに異なるURLを設定しています。各URLのメソッド内で、imwPageTypeに応じてさらに処理を分岐しています。

クライアントタイプ「PC」のURL一覧
URL jsp 画面種別
sample/im_workflow/tsfw/app/purchase/apply apply.jsp 申請画面
    申請(起票案件)画面
    一時保存画面
    再申請画面
sample/im_workflow/tsfw/app/purchase/approve approve.jsp 処理画面
sample/im_workflow/tsfw/app/purchase/confirm confirm.jsp 確認画面
sample/im_workflow/tsfw/app/purchase/detail detail.jsp 詳細画面
クライアントタイプ「SP」のURL一覧
URL jsp 画面種別
sample/im_workflow/tsfw/app/smartphone/purchase/apply apply_sp.jsp 申請画面(スマートフォン用)
    申請(起票案件)画面(スマートフォン用)
    一時保存画面(スマートフォン用)
    再申請画面(スマートフォン用)
sample/im_workflow/tsfw/app/smartphone/purchase/approve approve_sp.jsp 処理画面(スマートフォン用)
sample/im_workflow/tsfw/app/smartphone/purchase/confirm confirm_sp.jsp 確認画面(スマートフォン用)

コラム

画面種別の一覧については、以下のAPIドキュメントを参照してください。

注意

詳細画面については、クライアントタイプごとにURLが分かれておりません。
どちらのクライアントタイプでアクセスした場合でも共通のURLが呼び出されます。

5.5.2. 詳細画面のポップアップ表示

  • 詳細画面は各種一覧画面からポップアップにて表示されるため、グローバルナビが表示されないように設定する必要があります。

    ../../_images/detail.png
  • テーマ設定

    グローバルナビが表示されないモードでテーマが表示されるように、詳細画面のURLに対してHeadOnlyThemeBuilderを適用します。
    本書のサンプルでは、<%サンプルプログラムディレクトリ%>/src/main/conf/theme-head-only-path-config/im_workflow_tsfw_sample.xml で設定を行っています。
    <?xml version="1.0" encoding="UTF-8"?>
    <theme-head-only-path-config xmlns="http://www.intra-mart.jp/theme/theme-head-only-path-config"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.intra-mart.jp/theme/theme-head-only-path-config theme-head-only-path-config.xsd">
      <path>/sample/im_workflow/tsfw/app/purchase/detail</path>
    </theme-head-only-path-config>
    

    コラム

    テーマの仕様については、「 テーマ仕様書 」-「 PageBuilder 」を参照してください。

5.5.3. Controllerクラスの実装例(クライアントタイプ「PC」)

  • ルートURLの設定

    @RequestMappingアノテーションによってControllerクラス全体のルートURLをセットします。
    @Controller
    @RequestMapping("sample/im_workflow/tsfw/app/purchase")
    public class PurchaseController {
    
  • 申請画面表示処理

    • 申請画面

      ユーザデータIDを採番して画面にバインドします。
    • 申請(起票)画面

      案件が作成されているため、ユーザデータIDは採番しません。
    • 一時保存画面

      ユーザデータIDをキーにデータベースから入力済みのレコードを取得し、画面にバインドします。
      レコードが取得できない場合は、エラー画面へ遷移させます。
    • 再申請画面

      ユーザデータIDをキーにデータベースから入力済みのレコードを取得し、画面にバインドします。
      レコードが取得できない場合は、エラー画面へ遷移させます。
    /**
     * 申請画面表示処理
     * @param model モデル
     * @return 遷移先
     * @throws AccessSecurityException
     * @throws IOException
     */
    @RequestMapping(value = "apply")
    public String apply(final Model model, final PurchaseForm purchaseForm) throws AccessSecurityException, IOException {
    
        if (PageType.pageTyp_App.toString().equals(purchaseForm.getImwPageType())) {
            // 申請
            String userDataId = "";
            final Identifier identifier = new Identifier();
            userDataId = identifier.get();
    
            purchaseForm.setImwUserDataId(userDataId);
        } else if (PageType.pageTyp_UnApp.toString().equals(purchaseForm.getImwPageType())) {
            // 起票
        } else {
            // 一時保存 or 再申請
            SampleImwTPurchase matterData = repository.select(purchaseForm.getImwUserDataId());
            if (matterData == null) {
                final Message message = new Message();
                message.setTitle(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
                message.setMessage(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
                final String[] details = { MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.005") };
                message.setDetails(details);
                model.addAttribute(TransferView.MESSAGE, message);
                return TransferView.VIEW_NAME_ERROR;
            }
    
            purchaseForm.setItem_name(matterData.getItemName());
            purchaseForm.setItem_amount(matterData.getItemAmount());
            purchaseForm.setItem_price(matterData.getItemPrice());
            purchaseForm.setItem_comment(matterData.getItemComment());
    
        }
    
        model.addAttribute(purchaseForm);
    
        return "sample/im_workflow/tsfw/app/purchase/apply.jsp";
    }
    
  • 処理画面表示処理

    • 処理画面

      ユーザデータIDをキーにデータベースから入力済みのレコードを取得し、画面にバインドします。
      レコードが取得できない場合は、エラー画面へ遷移させます。
      /**
       * 処理画面表示処理
       * @param model モデル
       * @return 遷移先
       * @throws AccessSecurityException
       */
      @RequestMapping(value = "approve")
      public String approve(final Model model, final PurchaseForm purchaseForm) throws AccessSecurityException {
          SampleImwTPurchase matterData = repository.select(purchaseForm.getImwUserDataId());
      
          if (matterData == null) {
              final Message message = new Message();
              message.setTitle(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              message.setMessage(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              final String[] details = { MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.005") };
              message.setDetails(details);
              model.addAttribute(TransferView.MESSAGE, message);
              return TransferView.VIEW_NAME_ERROR;
          }
      
          purchaseForm.setItem_name(matterData.getItemName());
          purchaseForm.setItem_amount(matterData.getItemAmount());
          purchaseForm.setItem_price(matterData.getItemPrice());
          purchaseForm.setItem_total(matterData.getItemTotal());
          purchaseForm.setItem_comment(matterData.getItemComment());
      
          model.addAttribute(purchaseForm);
          return "sample/im_workflow/tsfw/app/purchase/approve.jsp";
      }
      
  • 確認画面表示処理

    • 確認画面

      ユーザデータIDをキーにデータベースから入力済みのレコードを取得し、画面にバインドします。
      レコードが取得できない場合は、エラー画面へ遷移させます。
      /**
       * 確認画面表示処理
       * @param model モデル
       * @return 遷移先
       * @throws AccessSecurityException
       */
      @RequestMapping(value = "confirm")
      public String confirm(final Model model, final PurchaseForm purchaseForm) throws AccessSecurityException {
          SampleImwTPurchase matterData = repository.select(purchaseForm.getImwUserDataId());
      
          if (matterData == null) {
              final Message message = new Message();
              message.setTitle(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              message.setMessage(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              final String[] details = { MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.005") };
              message.setDetails(details);
              model.addAttribute(TransferView.MESSAGE, message);
              return TransferView.VIEW_NAME_ERROR;
          }
      
          purchaseForm.setItem_name(matterData.getItemName());
          purchaseForm.setItem_amount(matterData.getItemAmount());
          purchaseForm.setItem_price(matterData.getItemPrice());
          purchaseForm.setItem_total(matterData.getItemTotal());
          purchaseForm.setItem_comment(matterData.getItemComment());
      
          model.addAttribute(purchaseForm);
          return "sample/im_workflow/tsfw/app/purchase/confirm.jsp";
      }
      
  • 詳細画面表示処理

    • 処理画面

      ユーザデータIDをキーにデータベースから入力済みのレコードを取得し、画面にバインドします。
      レコードが取得できない場合は、エラー画面へ遷移させます。
      クライアントタイプがスマートフォンの場合は、PCに切り替えます。
      /**
       * 詳細画面表示処理
       * @param model モデル
       * @return 遷移先
       * @throws AccessSecurityException
       */
      @RequestMapping(value = "detail")
      public final String detail(final Model model, final PurchaseForm purchaseForm) throws AccessSecurityException {
          SampleImwTPurchase matterData = repository.select(purchaseForm.getImwUserDataId());
      
          if (matterData == null) {
              final Message message = new Message();
              message.setTitle(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              message.setMessage(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              final String[] details = { MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.005") };
              message.setDetails(details);
              model.addAttribute(TransferView.MESSAGE, message);
              return TransferView.VIEW_NAME_ERROR;
          }
      
          purchaseForm.setItem_name(matterData.getItemName());
          purchaseForm.setItem_amount(matterData.getItemAmount());
          purchaseForm.setItem_price(matterData.getItemPrice());
          purchaseForm.setItem_total(matterData.getItemTotal());
          purchaseForm.setItem_comment(matterData.getItemComment());
      
          model.addAttribute(purchaseForm);
      
          // ショートカットURLからのアクセスかどうかを判定します。
          model.addAttribute("imwShortCutAccess", "1".equals(purchaseForm.getImwShortCutFlag()));
      
          // クライアントタイプがスマートフォンの場合は、PCに切り替えます。
          final ClientContext context = Contexts.get(ClientContext.class);
          if ("sp".equals(context.getClientTypeId())) {
              ClientTypeSwitcher.oneTimeSwitchTo("pc");
              model.addAttribute("isSmartPhone", true);
          }
      
          return "sample/im_workflow/tsfw/app/purchase/detail.jsp";
      }
      
  • エラーハンドリング処理

    • 例外ハンドラ

      例外クラスごとに@ExceptionHandlerを指定したメソッドにてエラーハンドリング処理を記述します。
      サンプルでは、例外が発生した場合にシステムエラー画面へ遷移させています。
      /**
       * エラーハンドリング処理
       * @param 例外クラス e
       * @return ModelAndView
       * @throws AccessSecurityException
       */
      @ExceptionHandler(Exception.class)
      public ModelAndView ExceptionHandler(Exception e) throws AccessSecurityException {
          final Message message = new Message();
          message.setTitle(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
          message.setMessage(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
          final String[] details = { MessageManager.getInstance().getMessage("SAMPLE.IMW.TSFW.ERR.001") };
          message.setDetails(details);
          return new ModelAndView(TransferView.VIEW_NAME_ERROR).addObject(TransferView.MESSAGE, message);
      }
      

5.5.4. Controllerクラスの実装例(クライアントタイプ「スマートフォン」)

  • ルートURLの設定

    @RequestMappingアノテーションによってControllerクラス全体のルートURLをセットします。
    @Controller
    @RequestMapping("sample/im_workflow/tsfw/app/smartphone/purchase")
    public class PurchaseSmartphoneController {
    
  • 申請画面(スマートフォン)表示処理

    • 申請画面(スマートフォン)

      ユーザデータIDを採番して画面にバインドします。
    • 申請(起票)画面(スマートフォン)

      案件が作成されているため、ユーザデータIDは採番しません。
    • 一時保存画面(スマートフォン)

      ユーザデータIDをキーにデータベースから入力済みのレコードを取得し、画面にバインドします。
      レコードが取得できない場合は、エラー画面へ遷移させます。
    • 再申請画面(スマートフォン)

      ユーザデータIDをキーにデータベースから入力済みのレコードを取得し、画面にバインドします。
      レコードが取得できない場合は、エラー画面へ遷移させます。
    /**
     * 申請画面(スマートフォン)表示処理
     * @param model モデル
     * @return 遷移先
     * @throws AccessSecurityException
     * @throws IOException
     */
    @RequestMapping(value = "apply")
    public String apply(HttpServletRequest request, final Model model, final PurchaseForm purchaseForm) throws IOException, AccessSecurityException {
        if (PageType.pageTyp_App_Sp.toString().equals(purchaseForm.getImwPageType())) {
            // 申請
            final Identifier identifier = new Identifier();
            String userDataId = identifier.get();
    
            purchaseForm.setImwUserDataId(userDataId);
        } else if (PageType.pageTyp_UnApp_Sp.toString().equals(purchaseForm.getImwPageType())) {
            // 起票
        } else {
            // 一時保存 or 再申請
            SampleImwTPurchase matterData = repository.select(purchaseForm.getImwUserDataId());
            if (matterData == null) {
                final Message message = new Message();
                message.setTitle(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
                message.setMessage(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
                final String[] details = { MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.005") };
                message.setDetails(details);
                model.addAttribute(TransferView.MESSAGE, message);
                return TransferView.VIEW_NAME_ERROR;
            }
    
            purchaseForm.setItem_name(matterData.getItemName());
            purchaseForm.setItem_amount(matterData.getItemAmount());
            purchaseForm.setItem_price(matterData.getItemPrice());
            purchaseForm.setItem_comment(matterData.getItemComment());
    
        }
    
        model.addAttribute(purchaseForm);
        model.addAttribute("homeUrl", getHomeUrl(request));
    
        return "sample/im_workflow/tsfw/app/purchase/apply_sp.jsp";
    }
    
  • 処理画面(スマートフォン)表示処理

    • 処理画面(スマートフォン)

      ユーザデータIDをキーにデータベースから入力済みのレコードを取得し、画面にバインドします。
      レコードが取得できない場合は、エラー画面へ遷移させます。
      /**
       * 処理画面(スマートフォン)表示処理
       * @param model モデル
       * @return 遷移先
       * @throws AccessSecurityException
       */
      @RequestMapping(value = "approve")
      public String approve(HttpServletRequest request, final Model model, final PurchaseForm purchaseForm) throws AccessSecurityException {
          SampleImwTPurchase matterData = repository.select(purchaseForm.getImwUserDataId());
      
          if (matterData == null) {
              final Message message = new Message();
              message.setTitle(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              message.setMessage(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              final String[] details = { MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.005") };
              message.setDetails(details);
              model.addAttribute(TransferView.MESSAGE, message);
              return TransferView.VIEW_NAME_ERROR;
          }
      
          purchaseForm.setItem_name(matterData.getItemName());
          purchaseForm.setItem_amount(matterData.getItemAmount());
          purchaseForm.setItem_price(matterData.getItemPrice());
          purchaseForm.setItem_total(matterData.getItemTotal());
          purchaseForm.setItem_comment(matterData.getItemComment());
      
          model.addAttribute(purchaseForm);
          model.addAttribute("homeUrl", getHomeUrl(request));
      
          return "sample/im_workflow/tsfw/app/purchase/approve_sp.jsp";
      }
      
  • 確認画面(スマートフォン)表示処理

    • 確認画面(スマートフォン)

      ユーザデータIDをキーにデータベースから入力済みのレコードを取得し、画面にバインドします。
      レコードが取得できない場合は、エラー画面へ遷移させます。
      /**
       * 確認画面(スマートフォン)表示処理
       * @param model モデル
       * @return 遷移先
       * @throws AccessSecurityException
       */
      @RequestMapping(value = "confirm")
      public String confirm(HttpServletRequest request, final Model model, final PurchaseForm purchaseForm) throws AccessSecurityException {
          SampleImwTPurchase matterData = repository.select(purchaseForm.getImwUserDataId());
      
          if (matterData == null) {
              final Message message = new Message();
              message.setTitle(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              message.setMessage(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
              final String[] details = { MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.005") };
              message.setDetails(details);
              model.addAttribute(TransferView.MESSAGE, message);
              return TransferView.VIEW_NAME_ERROR;
          }
      
          purchaseForm.setItem_name(matterData.getItemName());
          purchaseForm.setItem_amount(matterData.getItemAmount());
          purchaseForm.setItem_price(matterData.getItemPrice());
          purchaseForm.setItem_total(matterData.getItemTotal());
          purchaseForm.setItem_comment(matterData.getItemComment());
      
          model.addAttribute(purchaseForm);
          model.addAttribute("homeUrl", getHomeUrl(request));
      
          return "sample/im_workflow/tsfw/app/purchase/confirm_sp.jsp";
      }
      
  • エラーハンドリング処理

    • 例外ハンドラ

      例外クラスごとに@ExceptionHandlerを指定したメソッドにてエラーハンドリング処理を記述します。
      サンプルでは、例外が発生した場合にシステムエラー画面へ遷移させています。
      /**
       * エラーハンドリング処理
       * @param 例外クラス e
       * @return ModelAndView
       * @throws AccessSecurityException
       */
      @ExceptionHandler(Exception.class)
      public ModelAndView ExceptionHandler(Exception e) throws AccessSecurityException {
          final Message message = new Message();
          message.setTitle(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
          message.setMessage(MessageManager.getInstance().getMessage("SAMPLE.IMW.ERR.004"));
          final String[] details = { MessageManager.getInstance().getMessage("SAMPLE.IMW.TSFW.ERR.001") };
          message.setDetails(details);
          return new ModelAndView(TransferView.VIEW_NAME_ERROR).addObject(TransferView.MESSAGE, message);
      }