struts2值栈的奇怪现象:值栈不清空与值栈共享

一、起源

这次发现是来源一个我正在开发的系统的一个现象,用户A查询之后,B进入系统,但是查询条件居然是A的。这样说可能不清楚,换句话说就是A在查询时此action的值栈

会存入一些数据,但是当B进入时此值栈居然是A的值栈,而不是一个新的值栈(因为有a访问时存入的数据)。而以我的理解:每个永远会(每个线程)在访问action时,都会

创建一个值栈,当请求结束(即不请求该action)值栈会清除,而且最重要的是A是A的值栈,B是B的值栈。在经过我一些列的测试之后,结果让我非常惊讶:值栈不仅不会清

空,而且值栈是共用的资源。

二、测试

为此我专门写了一个action和一个jsp页面用于测试。
TestAction.java
package com.zs.action;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

public class TestAction extends MyBaseAction implements IMyBaseAction{

	String str;//测试用的属性
	List<String> sengMail=new ArrayList<String>();
	
	
	public String getStr() {
		return str;
	}
	public void setStr(String str) {
		this.str = str;
	}
	public List<String> getSengMail() {
		return sengMail;
	}
	public void setSengMail(List<String> sengMail) {
		this.sengMail = sengMail;
	}
	//-------------------------------------------------
	public String add() throws Exception {
		String mailstr=getRequest().getParameter("mailstr");
		sengMail.add(mailstr);
		return gotoQuery();
	}

	public void clearOptions() {
		// TODO Auto-generated method stub
		
	}

	public String delete() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public String gotoQuery() throws UnsupportedEncodingException {
		return SUCCESS;
	}

	public String queryOfFenye() throws UnsupportedEncodingException {
		// TODO Auto-generated method stub
		return null;
	}

	public String update() throws Exception {
		return gotoQuery();
	}

}
test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
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 'test.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>
  	<a href="<%=path %>/test!gotoQuery">测试</a>
  	<form action="<%=path %>/test!gotoQuery" method="post">
  		<input type="text" name="str"/>
  		<input type="submit"/>
  	</form>
  	${str }
  	<hr/>
  	模拟发邮件
  	<form action="<%=path %>/test!add" method="post">
  		假设这是我要发的邮件:<input type="text" name="mailstr"/>
  		<input type="submit"/>
  	</form>
  	<c:forEach items="${sengMail}" var="m">
  		${m }<br/>
  	</c:forEach>
  	<br/>
  	
  </body>
</html>

1,值栈是否会自动清空

第一次进入jsp页面时,是这样的,此时没有访问过action,然后在第一个文本框输入123,点击右边提交。

可以看到输入的值已经存入action的str。


当通过改地址栏到test.jsp,这样就意味着请求已结束,按照我的认知action的值栈会被清空,或者说在下一次访问时会被清空。

但是当点击测试,进入action时,发现值栈未被清空,123仍然显示出来了。

那么,这个结果说明值栈是不会被清空的,这与我之前的认知以及网上的说法不符,但既然事实是这样,我选择相信事实。

2,值栈是否是共享资源

紧接着上面的测试,这时我换一个浏览器用于模拟另一个用户访问,点击测试,进入action。


但结果是值栈存在,而且str的值仍然为123。

之后,我使用其他同事的电脑反复测试了几次,得到的结果仍然是一样的。那么,可以得出结论:值栈不仅不会自动清除,而且是所有线程的共有资源。基于此,我想到我的项目邮件提箱功能有一个问题:邮件经常会由于发送频率太快导致发送失败。为此之前我想的解决方案是:写一个公共的邮件发送者,它接受每个用户发送过来的邮件体(封装的邮件),然后按照顺序一个个排队发送,并设置间隔时间以防止频率过快。为实现这种效果我首先想到的是单例模式+观察者模式+资源池化。但这次的发现让我有了一个新的想法,既然action的值栈是公共资源,那么是否可以对它进行改造使它成为邮件发送者呢?期待我下次的测试结果吧。
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值