【问题标题】:In Struts2 Interceptors getting exception on an instance variable that is properly get/set in the interceptor在 Struts2 拦截器中,在拦截器中正确获取/设置的实例变量上出现异常
【发布时间】:2012-04-06 08:56:39
【问题描述】:

执行特定工作流时会出现此问题 -

  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)

我不明白这怎么可能,因为我在jsonStream 的拦截器中创建了公共 get/set 方法。我还在getJsonStream 方法中添加了一个sysout。事实证明它从未被调用过。

任何指针表示赞赏。

【问题讨论】:

  • Umesh 是正确的,拦截器需要是线程安全的。此外,拦截器不会像操作那样被压入堆栈。
  • @DaveNewton 注意。但我需要一些关于下一步做什么的指导。你能看看我对 Umesh 的回复并告诉我该怎么做吗?谢谢!

标签: java session struts2 variable-assignment interceptor


【解决方案1】:

我相信您的方法在这里是错误的,并且您没有按照应有的方式使用拦截器。 拦截器实例在动作之间共享。对于每个请求,S2 将创建一个新的动作实例,但拦截器将被重用,这意味着拦截器是无状态的,您正在尝试在拦截器中设置请求进程的状态。

我的建议是不要尝试将与请求处理相关的数据存储为它不属于拦截器角色的一部分。 只需检查 Ajax 请求响应并尝试查看您返回的结果,基于此您可以显示错误消息。

更新

检查会话超时处理的可能解决方案之一。这已在以下线程struts-2-session-timeout中进行了讨论

【讨论】:

  • 好点。我对 Struts2 比较陌生,我正在尝试遵循一些可能不正确的遗留代码逻辑。话虽如此,我应该如何解决这个问题。 1. 我应该检查请求是否是拦截器中的 ajax 吗? 2. 如果是,并且会话已过期,我是否应该只返回一个特殊字符串,例如“ajax_session_expired”。然后在我的一个全局结果中查找“ajax_session_expired”并让它返回正确的消息?再次感谢您的帮助。
  • @Chantz:最好的方法是通过 ajax 检查会话是否过期,一旦您知道会话过期,最好将用户重定向到任何预定义的页面,或者可以根据您的要求在同一页面上显示消息。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多