Tomcat下不同工程Session共享的思路 Demo

直接开门见山,针对一个Tomcat容器里不同工程Session无法共享问题,参考很多地方博客(会一一标注出处),搭建一个小Demo。

  问题来源:项目比较老的代码,有三个不同项目,菜单切换的时候访问到了不同项目下的请求,比如菜单1请求地址http://host:port/projectA/..........  菜单2请求地址:http://host:port/projectB/..........这些菜单都请求了相同的host  port,系统首先肯定登陆进来的,假设请求的都jsp(事实上,这个项目也的确是这样),每个项目请求到的jsp中都包含了这样一句<jsp:include page="/pub/UserInfo.jsp" flush="true"/> ,UserInfo.jsp里嵌套了部分js代码,将session中用户信息取出来;可是当不同工程切换的时候,session一会有,切换工程一会有没有了,项目比较复杂,session不宜于管理,排错真的不好找;另一种思路,session中信息替换为存到redis里,但是鉴于项目工程,所以打消了念头。

废话不多说直接进入正题了:

Step1.

新建两个简单的web工程SessionA以及SessionB(结构很简单,不多解释了.....代码会贴在step2)

Step2.

SessionA中SessionServlet代码:

package com.lvbinbin.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


public class SessionServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = -5130555166003468048L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		service(req, resp);
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
//		System.out.println("方法执行..."+req.getParameter("name"));
//		req.getSession().setAttribute("name", req.getParameter("name"));
//		PrintWriter pw = resp.getWriter();
//		pw.println("success done!"+req.getSession().getAttribute("name"));
		System.out.println("doService方法执行..."+req.getParameter("name"));
		req.getSession().setAttribute("name", req.getParameter("name"));
		ServletContext ctx1=req.getSession().getServletContext();
		ctx1.setAttribute("session", req.getSession());
		PrintWriter pw = resp.getWriter();
		pw.println("success done!"+((HttpSession)req.getServletContext().getAttribute("session")).getAttribute("name"));
	}
	
}

SessionA中web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SessionProjectA</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>servletA</servlet-name>
  	<servlet-class>com.lvbinbin.servlet.SessionServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>servletA</servlet-name>
  	<url-pattern>/sessionA</url-pattern>
  </servlet-mapping>
</web-app>

SessionA中index.jsp文件

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    Project:  SessionProjectA <br>
    <form action="sessionA">
    姓名:<input type="text" name="name"/><br/>
    <input type="submit" value="点击保存信息(lvbinbin)进入session"/>
    </form>
  </body>
</html>

 

SessionA就是这样简单,补充说明几句无关紧要的,ServletContext配置我会在Step3说明一下我的看法,随意看看:

    Tomcat6是不支持@WebServlet注解的,从Tomcat7开始支持Servlet3.0特性,Servlet3.0有很多新特性(感兴趣的可以自行百度,因为我就知道这么几个注解特性)

========================================华丽的分割线 SessionB==========================

SessionB的SessionServlet代码

package com.lvbinbin.servletB;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = -5130555166003468048L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		service(req, resp);
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		ServletContext ctx1 = req.getServletContext();
		ServletContext ctxA = ctx1.getContext("/SessionA");
		System.out.println("servletContext==null?"+(ctxA==null));
		HttpSession session=(HttpSession) ctxA.getAttribute("session");
		System.out.println("session==null?"+(session==null));
		System.out.println("session得到数据:"+session.getAttribute("name"));
		req.getRequestDispatcher("index.jsp").forward(req, resp);
	}

	
}

SessionB的web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SessionProjectA</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>servletB</servlet-name>
  	<servlet-class>com.lvbinbin.servletB.SessionServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>servletB</servlet-name>
  	<url-pattern>/sessionB</url-pattern>
  </servlet-mapping>
</web-app>

 

SessionB的index.jsp文件

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>SessionB</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  <body>
   Project:SessionProjectB.<br>
   <%
   		ServletContext ctx=application.getContext("/SessionA");
   		request.getSession().setAttribute("name", ((HttpSession)ctx.getAttribute("session")).getAttribute("name"));
   %>
  <h3>${sessionScope.name}</h3>
  </body>
</html>

代码部分就这么多了

 

Step3.Tomcat的配置以及补充说明

Eclipse里的server文件夹如下:

重点!把项目部署到Tomcat里,server.xml这样配置!

      <Context docBase="SessionA" path="/SessionA" reloadable="true" source="org.eclipse.jst.jee.server:SessionA"  crossContext="true"/>
      <Context docBase="SessionB" path="/SessionB" reloadable="true" source="org.eclipse.jst.jee.server:SessionB"  crossContext="true"/>

其中crossContext必须配置。参考地址( https://blog.csdn.net/jayyanzi/article/details/46561509 ),更详细的原因有人这么说:crosscontext="true"表示配置的不同context共享一个session 我菜,先人云亦云吧。

Step4.启动Tomcat:

浏览器访问SessionA:   http://localhost:8080/SessionA/

点击进入按钮

  

可知,Session中已经存了name值。

访问SessionB: http://localhost:8080/SessionB/sessionB

控制台打印:

emmmmm 这样应该对Session共享有一种思路了,ServletContext保存Session.我还要尝试WebLogic...因为项目就是Weblogic部署的

总结下本文的Demo,可能有价值的地方:

1.通过SessionB项目的request请求得到另外一个项目的ServletContext,进而得到Session对象

ServletContext ctx1 = req.getServletContext();
ServletContext ctxA = ctx1.getContext("/SessionA");
HttpSession session=(HttpSession) ctxA.getAttribute("session");

2.SessionB项目的index.jsp页面,我们可以利用application内置对象得到ServletContext,然后把session中的对象存到新的Session中,这样就可以只在UserInfo.jsp里改动一小部分代码,实现原有功能

 <%
   		ServletContext ctx=application.getContext("/SessionA");
   		request.getSession().setAttribute("name", ((HttpSession)ctx.getAttribute("session")).getAttribute("name"));
   %>

3.server.xml文件的配置属性,其中source属性应该是Eclipse生成的,各位小心点,别产生不必要的错误

<Context docBase="SessionA" path="/SessionA" reloadable="true" source="org.eclipse.jst.jee.server:SessionA"  crossContext="true"/>
<Context docBase="SessionB" path="/SessionB" reloadable="true" source="org.eclipse.jst.jee.server:SessionB"  crossContext="true"/></Host>

就这么多,我要肥家了,告辞各位!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值