文档章节

Struts2和SpringMVC整合方案(一):session回话管理

RedbullMT
 RedbullMT
发布于 2017/09/06 17:26
字数 830
阅读 30
收藏 0

背景:项目中使用的框架是Struts2,为了开发效率等因素,添加SpringMVC支持。

问题解析:

Struts2获取session方法:通过Action上下文ActionContext获取;

Action上下文ActionContext详细介绍:http://blog.csdn.net/john2522/article/details/7436599

SpringMVC如何兼容Struts2,如何统一获取session取值,如何保证SpringMVC和Struts2取到的session唯一。

解决方法:

解决此类问题需要先找两个框架共性,即http请求都是基于servlet线程实现的,单次请求,从开始到业务处理结束,其实都是在一个线程中实现。

web请求图如下图:

所以问题解决的方法就是从请求线程入手,只要能保证每次请求的HttpServletRequest、HttpServletResponse取到的值一样即可。

故很容易想到使用ThreadLocal线程变量,为保证SpringMVC取到的session唯一,在SpringMVC请求和Struts2请求都加上一层过滤器(基于请求url正则匹配:SpringMVC为**.do格式,Struts2为**.action格式),将取到的含有session的请求HttpServletRequest放到置空的线程变量中,每次请求结束将线程变量置空。进而实现SpringMVC和Struts2兼容。

相关代码如下:

TheadLocal管理类:

public class ThreadLocalManager
{

	/** The Constant requestLocal. */
	private static final ThreadLocal<HttpServletRequest> REQUEST_LOCAL = new ThreadLocal<HttpServletRequest>();
	/** The Constant responseLocal. */
	private static final ThreadLocal<HttpServletResponse> RESPONSE_LOCAL = new ThreadLocal<HttpServletResponse>();

	/**
	 * set httpServletRequst
	 * @param request
	 */
	public static void setHttpServletRequest(HttpServletRequest request)
	{
		REQUEST_LOCAL.set(request);
	}

	public static HttpServletRequest getHttpServletRequest()
	{

		return REQUEST_LOCAL.get();
	}

	/**
	 * set httpServletResponse
	 * @param request
	 */
	public static void setHttpServletResponse(HttpServletResponse response)
	{

		RESPONSE_LOCAL.set(response);
	}

	/**
	 * get httpServletResponse
	 * @return
	 */
	public static HttpServletResponse getHttpServletResponse()
	{

		return RESPONSE_LOCAL.get();
	}

	/**
	 * 清理需要清理的threadlocal
	 */
	public static void clearAllThreadLocalIfNeeded()
	{
		RESPONSE_LOCAL.remove();
		REQUEST_LOCAL.remove();
	}
}

SpringMVC拦截器:

1、在请求线程开始前线程变量为空,设置线程变量值;

2、处理相关业务;

3、结束设置线程变量为空。

public class SpringMvcFilter extends DispatcherServlet
{
	private static final long serialVersionUID = -307292166973012590L;

	protected static Logger logger = LoggerFactory.getLogger(SpringMvcFilter.class);

	@Override
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		logger.info("mvc....");
		// threadlocal 清理,防止异常中断导致的脏数据
		ThreadLocalManager.clearAllThreadLocalIfNeeded();

		logger.info("------------start-------------");
		// 主要为了适配老代码里很多地方调用struts2filter里的静态方法,防止service取不到值
		ThreadLocalManager.setHttpServletRequest(request);
		ThreadLocalManager.setHttpServletResponse(response);

		long startTime = System.currentTimeMillis();

		try
		{
			HttpSession session = request.getSession();
			if (null == session.getAttribute("user"))
			{
				logger.warn("未取到用户session url:{}", request.getRequestURL());
				if (request.getHeader("x-requested-with") != null
						&& request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest"))
				{
					responseJson(response, "未取到用户session!");
					return;
				}
				try
				{
					response.sendRedirect("/index.action");
					return;
				}
				catch (IOException e1)
				{
					e1.printStackTrace();
				}
				return;
			}
			super.doService(request, response);
		}
		catch (Exception e)
		{
			logger.info(e.getMessage());
		}
		finally
		{
			logger.info("------------end-------------");
			ThreadLocalManager.clearAllThreadLocalIfNeeded();

			long endTime = System.currentTimeMillis();

			logger.info("SpringMvcFilter request:[url]:" + request.getRequestURI() + ",[cost]:" + (endTime - startTime));

		}
	}

	private static void responseJson(HttpServletResponse response, String content)
	{
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json;charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter pw = null;
		try
		{
			pw = response.getWriter();
			pw.write(content);
			pw.flush();
		}
		catch (IOException e)
		{
			logger.error("响应结果失败", e);
		}
		finally
		{
			if (pw != null)
			{
				pw.close();
			}
		}
	}
}

同理Struts2拦截器类:

public class Struts2Filter extends StrutsPrepareAndExecuteFilter
{
	/** 日志. */
	protected static Logger logger = LoggerFactory.getLogger(Struts2Filter.class);

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
		ServletException
	{
		logger.info("struts2....");
		// 清理threadlocal,防止数据错乱
		ThreadLocalManager.clearAllThreadLocalIfNeeded();
		logger.info("------------start-------------");

		request.setCharacterEncoding("UTF-8");

		HttpServletRequest httpReq = (HttpServletRequest) request;
		HttpServletResponse httpRsp = (HttpServletResponse) response;

		ThreadLocalManager.setHttpServletRequest(httpReq);
		ThreadLocalManager.setHttpServletResponse(httpRsp);

		try
		{
			long startTime = System.currentTimeMillis();
			super.doFilter(httpReq, httpRsp, chain);
		}
		finally
		{
			logger.info("------------end-------------");
			ThreadLocalManager.clearAllThreadLocalIfNeeded();
		}
	}

	/**
	 * 获取当前线程的response.
	 * 
	 * @return the responseLocal
	 */
	public static HttpServletResponse getResponse()
	{
		return ThreadLocalManager.getHttpServletResponse();
		// return (HttpServletResponse) RESPONSE_LOCAL.get();
	}

	public static HttpSession getSession(boolean create)
	{
		HttpServletRequest req = ThreadLocalManager.getHttpServletRequest();
		if (req != null)
		{
			return req.getSession(create);
		}
		else
		{
			logger.info("未取到request");
		}
		return null;
	}

}

在web.xml中配置拦截器:

<filter>
	<filter-name>struts2</filter-name>
	<filter-class>
		com.**.**.core.filter.Struts2Filter
	</filter-class>
</filter>
<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>*.action</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>FORWARD</dispatcher>
</filter-mapping>

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <!-- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>-->
    	<servlet-class>com.**.**.core.filter.SpringMvcFilter</servlet-class>  
    <init-param>
        <param-name>contextConfigLocation</param-name>
		<param-value>classpath*:META-INF/spring/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

 

© 著作权归作者所有

共有 人打赏支持
RedbullMT
粉丝 2
博文 22
码字总数 5225
作品 0
南京
程序员
eclipse下搭建SSH整合环境(Struts2+Spring+Hibernate+maven)

1,创建一个maven工程,在选择Archetype时选择webapp: 2,下一步配置maven的pom.xml文件,获取依赖的jar包: <!-- struts2核心包 --><dependency> </dependency> <!-- struts2与spring整合的......

徐航
2014/05/08
0
5
细谈Spring(十一)深入理解spring+struts2整合(附源码)

Spring和struts2是我们在项目架构中用的比较多的两个框架,怎么才能把这两个框架用好,怎么来整合是我们掌握运用这两个框架的关键点,下面我们就怎么来整合,从哪来整合,为什么要整合,从这...

youyu2299
2013/12/06
0
0
Spring集成 Struts2

Spring如何整合struts2? 1) 整合目标? 使IOC容器来管理Struts2的Action! 2) 如何进行整合? ① 正常加入Struts2 ② 在Spring的IOC容器中配置Struts2的Action 特别注意:在IOC容器中配置S...

哎小艾
2017/11/08
0
0
基于maven的ssh框架一步一步搭建(一)

一、新建maven项目,配置ssh框架pom的最低支持 1、新建一个maven项目 2、添加一个web.xml <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-in......

漂泊者及其影子
2014/07/16
0
3
JAVA 并发编程- Spring 并发访问的线程安全性问题

首先对于Spring的IOC来说,对象是由Spring来帮我们管理,也就是在Spring启动的时候,在Spring容器中,由Spring给我们创建的,Spring会帮我们维护,一般都是单例的,也就是一个对象。 spring...

袁梓皓
2016/03/02
110
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

c语言之内存分配笔记

先看一个数组: short array[5] = {1,2} // 这儿定义的一个int类型的数组,数组第1和第2个元素值是1和2.其余后面默认会给值为0; 或者 short array[] = {1,2};//这儿数组第1和第2个元素,数组...

DannyCoder
今天
2
0
Shell | linux安装包不用选择Y/N的方法

apt-get install -y packageOR echo "y" | sudo apt-get install package

云迹
今天
2
0
Hadoop的大数据生态圈

基于Hadoop的大数据的产品圈 大数据产品的一句话概括 Apache Hadoop: 是Apache开源组织的一个分布式计算开源框架,提供了一个分布式文件系统子项目(HDFS)和支持MapReduce分布式计算的软件架...

zimingforever
今天
5
0
八大包装类型的equals方法

先看其中一个源码 结论:八大包装类型的equals方法都是先判断类型是否相同,不相同则是false,相同则判断值是否相等 注意:包装类型不能直接用==来等值比较,否则编译报错,但是数值的基本类型...

xuklc
今天
2
0
NoSQL , Memcached介绍

什么是NoSQL 非关系型数据库就是NoSQL,关系型数据库代表MySQL 对于关系型数据库来说,是需要把数据存储到库、表、行、字段里,查询的时候根据条件一行一行地去匹配,当量非常大的时候就很耗...

TaoXu
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部