2013-09-22 62 views
1

我正在修改我的表單,以便他們將在沒有啓用javascript的情況下工作,但也可以通過使用jQuery和AJAX與JavaScript協同工作。我使用的struts已被證明既有幫助也有痛苦。沒有使用JavaScript的表單處理通過基本的struts功能來處理,通過驗證和執行操作並分發回用戶所在的頁面,但是使用在表單html中設置的結果(actionMessage或actionError)。我有一個隱藏的輸入與頁面的URL將設置在表單bean中,這是struts.xml中的發送位置Struts2形式如下漸進增強工作,無需AJAX

我的問題是,我需要能夠有一些下面的功能增強的功能,如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字符串。 jquery插件能夠從該jsp中獲取結果,並將其追加到目標位置。但是這意味着如果我在JavaScript轉身時做了同樣的事情,一旦表單被提交,用戶將被分派到只顯示結果字符串的jsp,而不是將它們分派到同一頁面並在表單中設置消息。我也試圖使用struts2 json插件(這也很棒),但是這也只適用於jquery ajax,而不是當沒有javascript時。

有關如何讓表單在兩種設置中工作的任何想法? 謝謝!

+0

代碼不使用JavaScript,這是不一樣的,如果關閉JavaScript。 –

回答

1

我在struts攔截器的幫助下找到了它。我做了一個自定義攔截器,如果存在'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(); 
    } 

} 
+0

如果首先執行該操作,你會做什麼? –

+0

@RomanC爲什麼首先執行該操作?我在返回時調用該操作,並在調用之前執行無腳本檢查邏輯。 –

+0

是的,但正常的邏輯是在即將到來的請求上調用一個動作,然後返回一個結果。但是,如果沒有'noScript'參數不會攔截某些操作,它就不會涉及您的用例。 –