2

JavaScript を有効にしなくても機能するようにフォームを作り直していますが、jquery と AJAX を使用して JavaScript でもうまく機能します。私は、役に立つと同時に苦痛であることが証明されているストラットを使用しています。JavaScript を使用しないフォーム処理は、基本的な Struts 機能を使用して処理されました。アクションを検証して実行し、ユーザーがいるページにディスパッチして戻しますが、結果 (actionMessage または actionError) はフォーム html に設定されます。フォーム Bean に設定されるページの URL を含む非表示の入力がありました。これは struts.xml のディスパッチ場所です。

私の問題は、JSON シリアライゼーションや AJAX リクエストなどの拡張機能の下にこの機能を持たせる必要があることですが、両方を持つ方法がわかりません。以下は、正常に動作するスクリプトなしのフォームの構成とコードです。

struts.xml ファイル

<struts>
    <package name="default" extends="struts-default,json-default">
        <action name="contact" class="org.deadmandungeons.website.action.ContactAction" method="execute">
            <result name="success">%{currentPage}</result>
            <result name="input">%{currentPage}</result>
            <result name="error">%{currentPage}</result>
        </action>
    </package>
</struts>

ノースクリプト JSP

<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
<%@ taglib prefix="t" tagdir="/WEB-INF/tags"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<s:form id="contact_form" action="contact" method="post" cssClass="clearfix">
    <label for="contact_user">Username / In-game name:</label>
    <input type="text" id="contact_user" name="contactBean.username"
        class="field" data-enter-click="sendbutton" maxlength="16"
        size="16" />
    <label for="contact_email">Email:</label>
    <input type="text" id="contact_email" name="contactBean.email" class="field" data-enter-click="sendbutton" />
    <label for="contact_message">Message:</label>
    <textarea id="contact_message" name="contactBean.message" rows="5" cols="35"></textarea>
    <input id="no_script" name="contactBean.currentPage" type="hidden" value="${pageContext.request.requestURL}" />
    <div id="contact_response" class="response">
        <s:if test="hasActionErrors()">
            <s:actionerror id="contact_fail" cssClass="fail" />
        </s:if>
        <s:if test="hasActionMessages()">
            <s:actionmessage id="contact_success" cssClass="success" />
        </s:if>
    </div>
    <s:submit type="submit" id="sendbutton" value="Send" />
</s:form>

contactAction クラスは、必要なフィールドの ContactBean を保持し、検証されない場合は ActionErrors を追加し、成功した場合は ActionMessages を追加する基本的なアクション クラスです。

これに加えてjquery AJAXアプローチのために、私はいくつかのことを試しました。優れたプラグインである struts2 jquery プラグインがインストールされています。それを使用すると、フォーム上で ajax を動作させることができますが、上記の例のように struts 構成を使用することはできません。struts.xml の結果のディスパッチ場所については、次のような jsp ページに設定しました。

<%@ taglib prefix="s" uri="/struts-tags"%>
<s:property value="response" escapeHtml="false"/>

actionError または actionMessage 文字列を設定したばかりのアクション クラスに、response というフィールドを追加しました。jquery プラグインは、その jsp から結果を取得し、それをターゲットの場所に追加することができました。しかし、これは、javascript をオフにして同じことを行うと、フォームが送信されると、同じページにディスパッチしてメッセージをフォームに設定するのではなく、結果文字列のみを表示する JSP にユーザーがディスパッチされることを意味します。

また、struts2 json プラグイン (これも素晴らしい) を使用しようとしましたが、これも jquery ajax でのみうまく機能し、javascript がない場合には機能しません。

両方の設定でフォームを機能させる方法についてのアイデアはありますか? ありがとう!

4

1 に答える 1

2

ストラットインターセプターの助けを借りてそれを理解しました。「noScript」パラメーターが存在する場合にスタックパラメーターをチェックするカスタムインターセプターを作成しました。存在する場合は、「noScript」の結果を返します。noScript の結果は「チェーン」タイプであり、javascript がない場合にフォーム応答を処理するアクションに転送されます。noScript パラメータは、現在のページの URL を持つフォームの非表示フィールドを介して設定されます。ページが読み込まれると、jquery はこの入力をページのどこからでも削除します。そのため、JavaScript が無効になっている場合、noScript 入力は削除されません。後の私の新しい struts.xml は次のとおりです。

<struts>
    <package name="default" extends="struts-default,json-default">
        <interceptors>
            <interceptor name="noScriptInterceptor"
                class="org.deadmandungeons.website.NoScriptInterceptor"></interceptor>

            <interceptor-stack name="noScriptStack">
                <interceptor-ref name="noScriptInterceptor" />
                <interceptor-ref name="defaultStack" />
            </interceptor-stack>
        </interceptors>

        <action name="contact" class="org.deadmandungeons.website.action.ContactAction" method="execute">
            <interceptor-ref name="noScriptStack"/>
            <result type="json" name="success" />
            <result type="json" name="input" />
            <result type="json" name="error"/>
            <result type="chain" name="noScript">noScriptContact</result>
        </action>

        <action name="noScriptContact" class="org.deadmandungeons.website.action.ContactAction" method="execute">
            <result name="success">%{noScript}</result>
            <result name="input">%{noScript}</result>
            <result name="error">%{noScript}</result>
        </action>
    </package>
</struts>

NoScriptInterceptor クラスは次のとおりです。

public class NoScriptInterceptor implements Interceptor {

    private static final long serialVersionUID = -1472114260682759961L;

    @Override
    public void destroy() {
    }

    @Override
    public void init() {
    }

    @SuppressWarnings("unchecked")
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        final ActionContext context = invocation.getInvocationContext();

        String actionName = Utils.toCamelCase(invocation.getAction().getClass().getName());

        Map<String,Object> parameters = (Map<String,Object>)context.get(ActionContext.PARAMETERS);

        Object noScriptParam = parameters.get(actionName + ".noScript");
        if (noScriptParam != null) {
            return Constants.NO_SCRIPT;
        }

        return invocation.invoke();
    }

}
于 2013-09-22T16:46:06.147 に答える