文档章节

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

RedbullMT
 RedbullMT
发布于 2017/09/06 17:26
字数 830
阅读 40
收藏 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
南京
程序员
spring所创建的bean的作用域

spring 模式上的作用域有两种 singleton :一个 Spring容器 中只存在公用一个实例。 prototype : 在spring容器中,每次都产生一个新的实例。 值得注意的是,我上面所提到的 “spring容器” ...

小鸟00
09/06
0
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

没有更多内容

加载失败,请刷新页面

加载更多

【大福利】极客时间专栏返现二维码大汇总

我已经购买了如下专栏,大家通过我的二维码你可以获得一定额度的返现! 然后,再给大家来个福利,只要你通过我的二维码购买,并且关注了【飞鱼说编程】公众号,可以加我微信或者私聊我,我再...

飞鱼说编程
今天
1
0
Spring5对比Spring3.2源码之容器的基本实现

最近看了《Spring源码深度解析》,该书是基于Spring3.2版本的,其中关于第二章容器的基本实现部分,目前spring5的实现方式已有较大改变。 Spring3.2的实现: public void testSimpleLoad(){...

Ilike_Java
今天
1
0
【王阳明心学语录】-001

1.“破山中贼易,破心中贼难。” 2.“夫万事万物之理不外于吾心。” 3.“心即理也。”“心外无理,心外无物,心外无事。” 4.“人心之得其正者即道心;道心之失其正者即人心。” 5.“无...

卯金刀GG
今天
2
0
OSChina 周三乱弹 —— 我们无法成为野兽

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ _刚刚好: 霸王洗发水这波很骚 手机党少年们想听歌,请使劲儿戳(这里) hahahahahahh @嘻酱:居然忘了喝水。 让你喝可乐的话, 你准忘不了...

小小编辑
今天
9
0
vm GC 日志 配置及查看

-XX:+PrintGCDetails 打印 gc 日志 -XX:+PrintTenuringDistribution 监控晋升分布 -XX:+PrintGCTimeStamps 包含时间戳 -XX:+printGCDateStamps 包含时间 -Xloggc:<filename> 可以将数据保存为......

Canaan_
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部