文档章节

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

RedbullMT
 RedbullMT
发布于 2017/09/06 17:26
字数 830
阅读 51
收藏 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
2018/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
Java个人技术知识点总结(框架篇)

框架篇 Struts1的运行原理 在启动时通过前端总控制器ActionServlet加载struts-config.xml并进行解析,当用户在jsp页面发送请求被struts1的核心控制器ActionServlet接收,ActionServlet在用户...

java架构
2018/11/08
0
0
Spring集成 Struts2

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

哎小艾
2017/11/08
0
0
细谈Spring(十一)深入理解spring+struts2整合(附源码)

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

youyu2299
2013/12/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

关于php的xdebug配置(编辑器vscode)

虽然说echo和print_r是公认的最实用的调试工具,但是效率真的没有可视化的直接断点那么高。这里简单介绍如果安装及配置xdebug for vscode 一、PHP环境处的配置 1、编译安装 下载及编译php,因...

元谷
8分钟前
0
0
heartbeat

http://www.linux-ha.org/doc/users-guide/_building_and_installing_heartbeat_from_source.html kaer@linux-sqlf:~/Reusable-Cluster-Components-glue--0a7add1d9996> ./configure --enabl......

李有常
18分钟前
0
0
shell 脚本 title 免写入

1、有时候写脚本,需要写一些注释信息或者备注之类,当每次都手写比较麻烦,可以写一个脚本,每次运行则自动写入这些信息,不需要在手动输入; 通过 EOF 嵌入文档的方式; [root@localhost_002 sh...

芬野de博客
25分钟前
0
0
FragmentPagerAdapter+ViewPager 更新问题

场景 存在一种需求,当用户系统中,属于某一组织的用户登录之后(或者账户切换),要求主页面显示不同的ViewPager + Fragment组合,并且要求app无需退出就能刷新组合以及组合中的页面。 此外...

IamOkay
25分钟前
1
0
Python有哪些常用的标准库?Python基础教程,第十一讲,常用标准库(一)

上一节课我们学习了如何自定义模块,大家可以定义自己的模块,但是项目中通常不允许我们自己造轮子,所以本节课主要学习Python的标准库,学习使用别人的轮子,由于标准库内容较多,所以我们分...

程序员补给栈
33分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部