jsp中跨标签的会话管理

时间:2015-05-06 12:44:58

标签: java jsp session struts2 session-variables

技术 - Struts2& JSP

  1. 访问网址 - http://localhost:8080/session_acroos_tab/login.action

  2. 在Welcome.jsp中,用户在' First Text Field'中输入了一些值。并点击“第一个按钮'”。

  3. 单击此按钮(第一个按钮)时,将调用LoginAction.java的firstButtonClick函数。
  4. 现在控件将再次转移到Welcome.jsp。在用户输入的第一个文本字段'中输入的jsp值显示,
  5. 用户应在' Second Text Field'中输入一些值。并点击第二个按钮'。
  6. 单击此按钮(第二个按钮)时,将调用LoginAction.java的secondButtonClick函数,控件将再次转到Welcome.jsp页面。
  7. 在执行第5步之前,如果用户打开新选项卡并执行步骤1到3并再次返回选项卡1并执行剩余步骤,则所有会话数据都会搞乱。我知道,所有打开的新标签应该共享相同的会话,但解决方案是什么。我想独立完成两个标签。

    Welcome.jsp中

    <%@ page contentType="text/html; charset=UTF-8"%>
    <%@ taglib prefix="s" uri="/struts-tags"%>
    <head> 
    <title>Welcome</title>
    <script type="text/javascript">
    function clickSecondButton(form)
    {
        form.action="secondButtonClickForm2";
        form.submit(); 
    }
    </script>
    </head>
    <s:form action="firstButtonClickForm2" method="post">
        <s:if test="%{#session.HIDE_FIRST_BUTTON!=null}">
            <ul>
                <li>FIRST TEXT FIELD VALUE - <s:property value="%{#session.FIRST_TEXT_FIELD}"/></li>
            </ul>
            <s:textfield name="secondtextfield" key="label.secondtextfield" size="20"></s:textfield>
            <s:submit key="label.secondButton" align="center" onclick="clickSecondButton(this.form)"></s:submit>
        </s:if>
        <s:else>
            <s:textfield name="firsttextfield" key="label.fisttextfield" size="20"></s:textfield>
            <s:submit key="label.firstButton" align="center"></s:submit>
        </s:else>
    </s:form>
    

    LoginAction.java

    package net.patel.struts2;
    import java.util.Map;
    import com.opensymphony.xwork2.ActionContext;
    
    public class LoginAction {
      private String username;
      private String password;
      private String firsttextfield;
      private String secondtextfield;    
    
      public String execute() {
        Map session = (Map) ActionContext.getContext().getSession();
        session.clear();
        if (this.username==null)
            return "success";
    
        if (this.username.equals("admin") 
                && this.password.equals("admin123")) {
            return "success";
        } else {
            return "error";
        }
      }
    
      public String firstButtonClick() {
      System.out.println("{firstButtonClick} "+firsttextfield);
      Map session = (Map) ActionContext.getContext().getSession();
      session.put("HIDE_FIRST_BUTTON", "Y");
      //session.put("FIRST_TEXT_FIELD", firsttextfield);
      return "success";
      }
    
      public String secondButtonClick() {
      Map session = (Map) ActionContext.getContext().getSession();
      System.out.println("{secondButtonClick} firsttextfield-"+session.get("FIRST_TEXT_FIELD")+" II TF-"+secondtextfield);
    
      return "success";
      }
    
      public String getUsername() {
          return username;
      }
    
      public void setUsername(String username) {
        this.username = username;
      }
    
      public String getPassword() {
        return password;
      }
    
      public void setPassword(String password) {
        this.password = password;
      }
    
      public String getFirsttextfield() {
        return firsttextfield;
      }
    
      public void setFirsttextfield(String firsttextfield) {
        this.firsttextfield = firsttextfield;
      }
    
      public String getSecondtextfield() {
        return secondtextfield;
      }
    
      public void setSecondtextfield(String secondtextfield) {
        this.secondtextfield = secondtextfield;
      }
    
    }
    

    struts.xml中

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
    <struts>
        <constant name="struts.enable.DynamicMethodInvocation" value="false" />
        <constant name="struts.devMode" value="true" />
        <constant name="struts.custom.i18n.resources" value="ApplicationResources"></constant>
        <package name="default" extends="struts-default" namespace="/">
        <action name="login" class="net.viralpatel.struts2.LoginAction">
            <result name="success">Welcome.jsp</result>
            <result name="error">Login.jsp</result>
        </action>    
        <action name="*Form2" class="net.viralpatel.struts2.LoginAction" method="{1}">
            <result name="success">Welcome.jsp</result>
            <result name="error">Login.jsp</result>
        </action>    
        </package>
      </struts>
    

    ApplicationResources.properties

     label.username= Username
     label.password= Password
     label.login= Login 
     label.fisttextfield=First Text Field
     label.firstButton=First Button
     label.secondtextfield=Second Text Field
     label.secondButton=Second Button
    

    尝试更清楚,我在这个问题上缺乏想法,即使这听起来像是一个经典:我花了好几个小时试图玩这个但是无处可去。你的帮助非常感谢。

2 个答案:

答案 0 :(得分:3)

您可以使用HTML5 SessionStorage(window.sessionStorage)。您将生成随机ID并保存在会话存储每个浏览器选项卡中。然后每个浏览器选项卡都有自己的ID。

&#34;使用sessionStorage存储的数据不会在浏览器选项卡中保留,即使两个选项卡都包含来自同一域来源的网页也是如此。换句话说,sessionStorage中的数据不仅限于调用页面的域和目录,而且还包含页面所在的浏览器选项卡。与会话cookie的对比,会将数据从选项卡保留到选项卡。&# 34;

答案 1 :(得分:1)

您将始终需要一个令牌。它可以生成和维护server-side(Java)和client-sideHTML5 sessionStorage)。

然后,它可用于通过参数化将某个页面/标签固定到某组会话属性。

服务器端方式的一个示例是在由所有其他人扩展的BaseAction中生成令牌。在拦截器中做它会更好,但这取决于你。

在这种情况下,因为它不是安全令牌(例如,用于对抗XSRF的令牌,需要无法预测),您可以将当前时间用作令牌

E.g。服务器端令牌:

public abstract class BaseAction extends ActionSupport 
                                  implements SessionAware {

    private Map<String,Object>  session;       
    private String token;

    public void setSession(Map<String,Object> session) {
        this.session = session;
    }
    public void setToken(String token) {
        // Retrieve the Token from the page, if any
        this.token = token;
    }
    public String getToken() {
        if (token==null){
            // Generates a new Token, only if it has not been passed from the JSP
            token = System.currentTimeMillis();
        }       
        return token;
    }
    public void setTokenSessionAttribute(String k, Object v){
        session.putSessionAttribute(getToken() + "_" + k,v);
    }
    public Object getTokenSessionAttribute(String k){
        return session.getSessionAttribute(getToken() + "_" + k);
    }


    public String execute(){
        return SUCCESS;
    }

    public String firstButtonClick() {
        setTokenSessionAttribute("FIRST_TEXT_FIELD", firstTextField);
        return SUCCESS;
    }

    public String secondButtonClick() {
        log.debug("Saved value was: " + getTokenSessionAttribute("FIRST_TEXT_FIELD"))
        return SUCCESS;
    }
    private String firstTextField; // with setter

}
JSP中的

<s:form ... >
    <!-- stuff -->
    <s:hidden name="token" />
    <!-- stuff -->
    <s:if test="%{#session[token+'HIDE_FIRST_BUTTON']!=null}">
        <!-- stuff -->
    <!-- stuff -->
</s:form>

这是众多方法中的一种,例如,您可以在操作中创建一个方法,返回正确的参数化会话属性:

public Object getTabSessionObj(String k){
    return session.get(token + "_" + k);
}
<s:if test="%{getTabSessionObj('HIDE_FIRST_BUTTON')!=null}">