簡體   English   中英

跨jsp選項卡的會話管理

[英]session management across tabs in jsp

技術-Struts2和JSP

  1. 訪問URL- http:// localhost:8080 / session_acroos_tab / login.action

  2. 在Welcome.jsp中,用戶在“第一個文本字段”中輸入一些值,然后單擊“第一個按鈕”。

  3. 在點擊這個按鈕(第一個按鈕),中firstButtonClick功能LoginAction.java被調用。
  4. 現在,控件將再次轉移到Welcome.jsp 在用戶在“第一個文本字段”中輸入的該jsp值上,
  5. 用戶應在“第二文本字段”中輸入一些值,然后單擊“第二按鈕”。
  6. 在點擊這個按鈕(第二個按鈕),中secondButtonClick功能LoginAction.java被調用,控制應再去Welcome.jsp頁。

在執行第5步之前,如果用戶打開新選項卡並從第1步執行到第3步,然后再次返回到Tab-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

嘗試更清楚一點,我在這個問題上缺乏主意,即使聽起來像是經典:我花了數小時試圖解決這個問題,但是卻一無所獲。非常感謝您的幫助。

您可以使用HTML5 SessionStorage(window.sessionStorage)。 您將生成一個隨機ID,並按“瀏覽器”選項卡保存在會話存儲中。 然后,每個瀏覽器選項卡都有自己的ID。

“使用sessionStorage存儲的數據不會在瀏覽器選項卡之間持久化,即使兩個選項卡都包含來自同一域來源的網頁。換句話說,sessionStorage內部的數據不僅限於調用頁面的域和目錄,還限於瀏覽器選項卡其中包含頁面。將其與會話cookie進行對比,會話cookie確實會在標簽之間保留數據。”

您將始終需要令牌。 它可以在server-side (Java)和client-sideHTML5 sessionStorage )生成和維護。

然后,可以通過參數化它們,將某個頁面/選項卡固定到一組會話屬性。

服務器端方式的一個示例是在所有其他擴展的BaseAction中生成令牌。 最好在攔截器中執行此操作,但這取決於您。

在這種情況下, 由於它不是安全令牌 (例如,用於XSRF的令牌,需要不可預測),因此可以將當前時間用作令牌。

例如服務器端令牌:

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}">

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM