Java 在Struts2拦截器中,对在拦截器中正确获取/设置的实例变量获取异常

Java 在Struts2拦截器中,对在拦截器中正确获取/设置的实例变量获取异常,java,session,struts2,variable-assignment,interceptor,Java,Session,Struts2,Variable Assignment,Interceptor,执行特定工作流时会出现此问题- 用户已登录 会话到期 用户试图在当前页面上执行触发AJAX请求的操作 由于会话已过期,ajax请求将失败 我需要显示一条这样的信息 现在问题出现了。我有一个拦截器,它可以正确地捕获会话过期的消息。它还正确地标识了原始请求是AJAX。因此,这意味着拦截器需要使用json响应(接受任何ajax调用的输入格式)进行响应 拦截器代码- public class AuthenticationInterceptor implements Interceptor {

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

  • 用户已登录
  • 会话到期
  • 用户试图在当前页面上执行触发AJAX请求的操作
  • 由于会话已过期,ajax请求将失败
  • 我需要显示一条这样的信息
  • 现在问题出现了。我有一个拦截器,它可以正确地捕获会话过期的消息。它还正确地标识了原始请求是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;
    }
    
    我不明白这是怎么可能的,因为我在
    jsonStream
    的拦截器中创建了公共get/set方法。我还在
    getJsonStream
    方法中放入了一个sysout。事实证明它从未被调用过


    任何指针都值得赞赏。

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

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

    更新


    检查会话超时处理的可能解决方案之一。这已在下面的线程中讨论过。如果Umesh正确,拦截器需要是线程安全的。此外,拦截器不会像操作一样被推到堆栈上。@DaveNewton指出。但我需要一些关于下一步做什么的指导。你能看看我对乌梅什的回复,告诉我怎么做吗?谢谢说得好。我对Struts2比较陌生,我试图遵循一些遗留代码逻辑,这可能不正确。话虽如此,我该如何着手解决这个问题。1.我是否应该检查请求在拦截器中是否是ajax?2.如果是,并且会话已经过期,我是否应该返回一个特殊字符串,比如“ajax\u session\u expired”。然后在我的一个全局结果中查找“ajax\u session\u expired”&让它返回正确的消息?再次感谢您的帮助。@Chantz:最好的方法是通过ajax检查会话是否过期,一旦您知道会话已过期,最好将用户重定向到任何预定义页面,或者根据您的要求在同一页面上显示消息。
    <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)