2012-03-21 60 views
3

這個問題的實例變量執行特定工作流時出現 -在Struts2的攔截器得到例外的要求正確獲取/在攔截器設置

  1. 用戶已經登錄
  2. 會話過期
  3. 用戶嘗試在觸發AJAX請求的當前頁面上執行某些操作
  4. 由於會話已過期,所以ajax請求失敗
  5. 我需要顯示一條消息以實現此效果。

現在問題出現了。我有一個攔截器,可以正確捕獲會話過期。它也正確地標識出原始請求是AJAX。所以這意味着攔截器需要響應一個json響應(接受任何我的ajax調用的輸入格式)。

攔截代碼 -

public class AuthenticationInterceptor implements Interceptor { 

    private InputStream jsonStream; 

    @Override 
    public String intercept(ActionInvocation actionInvocation) throws Exception { 
    ... // boilerplate init code. 
    if (memberId == null 
     && StringUtils.equals("XMLHttpRequest", request.getHeader("X-Requested-With"))) { 

     Map<String, Object> responseObject = Maps.newHashMap(); 
     Set<String> errors = Sets.newHashSet(); 
     errors.add("Your session has expired. Please refresh page and login."); 

     responseObject.put("errors", errors); 
     responseObject.put("success", false); 

     jsonStream = ResponseUtils.getJSONResponseStream(responseObject); 

     return "json"; 
    } 
} 


public InputStream getJsonStream() { 
    return jsonStream; 
} 

public void setJsonStream(InputStream jsonStream) { 
    this.jsonStream = jsonStream; 
} 

struts.xml的碼 -

<package name="raisin" namespace="/raisin" extends="secure"> 
    <interceptors> 
     <interceptor name="authentication" class="interceptors.AuthenticationInterceptor"/> 
    </interceptors> 
    <global-results> 
     <result name="json" type="stream"> 
     <param name="contentType">application/json</param> 
     <param name="inputName">jsonStream</param> 
     <param name="bufferSize">1024</param> 
     </result> 
    </global-results> 
    ... 
    </package> 

所以,當這個工作流執行我得到下面的異常 -

java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [jsonStream] in the invocation stack. Check the &lt;param name=&quot;inputName&quot;&gt; tag specified for this action. 
    org.apache.struts2.dispatcher.StreamResult.doExecute(StreamResult.java:237) 
    org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186) 
    com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:373) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:277) 
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52) 
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:498) 

我不要緊tand,因爲我在jsonStream的攔截器中創建了公開的get/set方法,這怎麼可能呢。另外我在getJsonStream方法中加入了sysout。事實證明,它從未被稱爲。

任何指針讚賞。

+3

Umesh製作是正確的,攔截器必須是線程安全的討論。另外,攔截器不會像動作一樣被壓入棧中。 – 2012-03-22 03:13:18

+0

@DaveNewton注意。但我需要一些關於接下來要做什麼的指導。你能否看看我對Umesh的迴應,並告訴我該怎麼做?謝謝! – Chantz 2012-03-22 13:22:54

回答

3

我相信你的做法在這裏是錯誤的,你沒有按照他們應該使用的方式使用攔截器。 攔截器實例在動作中共享。對於每個請求,S2將創建一個新的動作實例,但攔截器將被重用,這意味着攔截器是無狀態的,並且您嘗試在攔截器中設置請求過程的狀態。

我的建議是不要嘗試存儲與請求處理相關的數據,因爲它不是Interceptor角色的一部分。 只需檢查Ajax請求響應,並嘗試查看返回的結果,然後根據該結果顯示錯誤消息。

更新

一個可能的解決方案,以檢查會話超時handling.This已經在下列螺紋struts-2-session-timeout

+0

好點。我對Struts2相對來說比較新,我正在嘗試遵循一些遺留的代碼邏輯,這可能不正確。說過了,我該如何解決這個問題。 1.我應該檢查請求是否是攔截器中的ajax? 2.如果是,如果會話已過期,我應該只返回一個特殊的字符串,如「ajax_session_expired」。然後在我的全局結果中查找「ajax_session_expired」並讓它返回正確的消息? 再次感謝您的幫助。 – Chantz 2012-03-22 13:18:14

+0

@Chantz:最好的方法是通過ajax檢查會話過期,並且一旦您知道會話已過期,則可以更好地將用戶重定向到任何預定義的頁面,或者可以根據您的要求在同一頁面上顯示消息。 – 2012-03-22 14:45:02

+0

@Chantz:看到我更新的答案 – 2012-03-22 14:52:43