1. 程式人生 > >java結合wabacus實現session跨域、session共享(第二版)

java結合wabacus實現session跨域、session共享(第二版)

宣告:該版相對於第一版有所改進。原因:每一版存在session覆蓋問題,分析如下:

request().getServletContext().setAttribute("globelSession", session);

我們可以把globelSession想象成是索引,或某一搜索條件。每一次請求都搜尋名為globelSession的session,而globelSession是指定的,每一次set的session都名為globelSession,所以session將會被更新,即:覆蓋。

解決辦法:瀏覽器每一次請求所產生的sessionid都不重複,因此,我們可以將這個sessionid想象成主鍵ID或索引,ID不重複,查詢出來的資料也不會是同一條,因此能夠有效地避免session覆蓋。程式碼如下:

HttpSession session = request().getSession();
request().getServletContext().setAttribute(session.getId(), session);

一、完整程式碼:

System.out.println("==============================啟用SESSION共享(跨域)===============================");
HttpSession session = request().getSession();
session.setAttribute("userPA01", user.getPA01());
session.setAttribute("userName", user.getUserName());
// 注意這裡,要傳遞sessionID過去,目的:避免session覆蓋
request().getServletContext().setAttribute(session.getId(), session);
//request().getServletContext().setAttribute("globelSession",  session);
/*Cookie[] cookies = request().getCookies();
for (Cookie cookie : cookies) {
System.out.println("登入時cookies:"+cookie.getValue());
}*/
System.out.println("================================"+session.getId()+"==============================");

在另一個工程下新建servlet測試類Global.java

protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	ServletContext context = request.getServletContext().getContext("/app2");
	HttpSession session = (HttpSession) context.getAttribute(session.getId());
	System.out.println("跨域獲取到的" + session.getAttribute("userPA01"));
}

此時,需要修改web.xml檔案,即:請求的入口

<!-- session跨域、共享(測試用) -->
<!-- <servlet>
  <description>This is the description of my J2EE component</description>
  <display-name>This is the display name of my J2EE component</display-name>
  <servlet-name>Global</servlet-name>
  <servlet-class>com.perfect.util.Global</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>Global</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping> -->

server.xml配置:

<Context docBase="D:\WorkSpace\WabacusBlank\WebRoot" path="/OA" reloadable="true" crossContext="true" sessionCookiePath="/"/>
<Context docBase="D:\WorkSpace\PerfectOA\target\oa" path="/" reloadable="true" crossContext="true" sessionCookiePath="/"/>

當你啟動app1工程並登入後,執行app2即可獲取app1共享的session。

二、在wabacus中的用法,必須遵循wabacus的語法

首先,在wabacus.cfg.xml中配置全域性攔截器,程式碼如下:

<!-- 配置全域性攔截器 -->
<global-interceptors>
	<interceptor class="com.perfect.interceptor.DataSessionIntercetor"/>
</global-interceptors>

建立攔截器DataSessionIntercetor.java

package com.perfect.interceptor;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.wabacus.system.ReportRequest;
import com.wabacus.system.intercept.AbsPageInterceptor;

public class DataSessionIntercetor extends AbsPageInterceptor {
	public void doStart(ReportRequest rrequest) {
		System.out.println("您進入攔截器!");
		System.out.println("++++++++++++++++++獲取共享session資訊如下:++++++++++++++++++");
		ServletContext context = rrequest.getRequest().getServletContext().getContext("/");
//		HttpSession session = (HttpSession) context.getAttribute("globelSession");
		String wabSessionID = rrequest.getRequest().getRequestedSessionId();
		System.out.println("wabacus操作動作產生的sessionid:" + wabSessionID);
		if (wabSessionID.indexOf("-") != -1) {
			rrequest.getRequest().getSession().setAttribute("sessionid", wabSessionID);
			String sessionid = (String)rrequest.getRequest().getSession().getAttribute("sessionid");
			System.out.println("使用者登入時產生的sessionid:" + sessionid);
			if (context != null) {
				HttpSession session = (HttpSession) context.getAttribute(sessionid);
				rrequest.getRequest().getSession().setAttribute("userid", session.getAttribute("userPA01"));
				rrequest.getRequest().getSession().setAttribute("username", session.getAttribute("userName"));
				System.out.println("當前使用者ID(PA01):" + session.getAttribute("userPA01"));
				System.out.println("當前使用者姓名:" + session.getAttribute("userName"));
				rrequest.setAttribute("userid", rrequest.getRequest().getSession().getAttribute("userid"));
				rrequest.setAttribute("username", rrequest.getRequest().getSession().getAttribute("username"));
			}
		}
		/*Cookie[] cookies = rrequest.getRequest().getCookies();
		for (Cookie cookie : cookies) {
			System.out.println("cookies:"+cookie.getValue());
		}*/
	}

}

為什麼會有wabSessionID.indexOf("-") != -1這樣的判斷?

因為瀏覽器訪問不能服務時生成的sessionid會有所不同,如下圖,每二個id才是登入時產生的sessionid,而第一個則是訪問wabacus服務時產生的sessionid

1、在xml頁面上的使用

<sql>
	<value>
		<![CDATA[SELECT (SELECT COUNT(*) c FROM A25 WHERE {#condition#}) c,c01,c02 FROM A25 WHERE {#condition#} order by c07 desc]]>
	</value>
	<condition name="userid" label="操作人" hidden="true" source="session{userid}">
		<value>
			<![CDATA[c05 = '#data#']]>
		</value>
	</condition>
	
</sql>

2、在其它攔截器中使用

// ***************************當前使用者操作**************************** //
String userPA01 = (String) rrequest.getRequest().getSession().getAttribute("userid");
String userName = (String) rrequest.getRequest().getSession().getAttribute("username");
// ****************************************************************** //