现在的位置: 首页 > 综合 > 正文

Spring和Struts2整合见问题之一

2012年10月13日 ⁄ 综合 ⁄ 共 5742字 ⁄ 字号 评论关闭

最近在做一个模拟网上银行小系统时遇到了问题,自己怎么也调不出来,然后各种百度,并在多个论坛上提问,问题终于在传智论坛上被于洋老师给指出来了,真是非常感谢!

下面说一下我遇到的问题:

Struts2中Action代码如下:

@Service("transactionAction")
public class TransactionAction extends ActionSupport {
	@Resource
	private TransactionBiz transactionBiz;
	@Resource
	private UserBiz userBiz;
	private Account account;
	private TransactionLog log;
	private Pager pager;
	
	/**
	 * 存款
	 * @return
	 */
	public String deposit(){
		//调用自定义方法isEnable判断账户是否冻结
		if(isEnable()){
			System.out.println(account.getBalance()+"存款");
			//使用执行isEnable方法从session中重新获取的账户对象,给交易信息对象log中关联的账户对象属性赋值
			log.setAccount(account);
			ServletActionContext.getRequest().getSession().setAttribute("account", account);
			//调用业务方法,更新账户表Account表中的余额,并在交易信息表transaction_log中添加交易记录
			return isSuccess(transactionBiz.deposit(log));
		}
		return "message";
	}	
	/**
	 * 取款页面验证
	 */
	public void validateWithdrawal(){
		//比较取款页面输入的金额与账户余额
		account = (Account) ServletActionContext.getRequest().getSession().getAttribute("account");
		if(log.getTrMoney()>account.getBalance()){
			System.out.println("***");
			this.addFieldError("trMoney","您的账户余额不足!");
		}
	}
	/**
	 *  取款
	 * @return
	 */
	public String withdrawal(){
		if(isEnable()){
			log.setAccount(account);
			ServletActionContext.getRequest().getSession().setAttribute("account", account);
			return isSuccess(transactionBiz.withdrawal(log));
		}
		return "message";
	}
	/**
	 * 转账页面验证
	 */
	public void validateTransfer(){
		account = (Account)ServletActionContext.getRequest().getSession().getAttribute("account");
		if(log.getOtherid().intValue()==account.getAccountid().intValue()){
			this.addFieldError("log.otherid", "您不能转账给自己!");
		}
		if(userBiz.getAccount(log.getOtherid())==null){
			this.addFieldError("log.otherid", "该账户不存在!");
		}
		if(log.getTrMoney()>account.getBalance()){
			this.addFieldError("log.trMoney", "您的账户余额不足!");
		}
	}
	/**
	 * 转账
	 * @return
	 */
	public String transfer(){
		if(isEnable()){
			log.setAccount(account);
			ServletActionContext.getRequest().getSession().setAttribute("account", account);
			return isSuccess(transactionBiz.transfer(log));
		}
		return "message";
	}
	/**
	 * 分页显示交易记录
	 * @return
	 */
	public String list(){
		System.out.println(pager.getCurPage());
		account = (Account)ServletActionContext.getRequest().getSession().getAttribute("account");
		//获取待显示页的页码
		int curPager = pager.getCurPage();
		//根据待显示页的页码和账户对象获取交易记录
		List<TransactionLog> logs = transactionBiz.getLogs(account, curPager);
		//获得账户的交易记录总数,用来初始化分页类Pager对象,并设置其PerPageRows和rowCount属性
		pager = transactionBiz.getPagerOfLogs(account);
		//设置Pager对象中的待显示页页码
		pager.setCurPage(curPager);
		ServletActionContext.getRequest().setAttribute("logs", logs);
		return "success";
	}
	
	/**
	 * 自定义方法,判断账户是否冻结
	 * @return
	 */
	private boolean isEnable(){
		//从session中重新获取Account对象,该对象在登录成功时已保存到session中
		account = (Account)ServletActionContext.getRequest().getSession().getAttribute("account");
		userBiz.reflush(account);
		if(account.getStatus().getName().equals("冻结")){
			ActionContext.getContext().put("message", "对不起!该账户已被冻结,无法进行相关操作<br>");
			return false;
		}
		return true;
	}
	/**
	 * 自定义方法,根据执行结果,显示操作成功或失败信息
	 * @param flag
	 * @return
	 */
	private String isSuccess(boolean flag){
		if(flag){
			ActionContext.getContext().put("message", "操作成功!");
			return "message";
		}
		ActionContext.getContext().put("message", "操作失败!<a href='javascript:history.go(-1)'>返回</a>");
		return "message";
	}	
	
	
	
	public TransactionLog getLog() {
		return log;
	}
	public void setLog(TransactionLog log) {
		this.log = log;
	}
	public Pager getPager() {
		return pager;
	}
	public void setPager(Pager pager) {
		this.pager = pager;
	}
}

 

struts.xml配置如下:

<package name="transaction" namespace="/transaction" extends="struts-default">
		<action name="deposit" class="transactionAction" method="deposit">
			<result name="message">/message.jsp</result>
 			<result name="input">/deposit.jsp</result>	
		</action>
		<action name="withdrawal" class="transactionAction" method="withdrawal">
			<result name="message">/message.jsp</result>
			<result name="input">/withdrawal.jsp</result>
		</action>
		<action name="transfer" class="transactionAction" method="transfer">
			<result name="message">/message.jsp</result>
			<result name="input">/transfer.jsp</result>
		</action>
		<action name="list" class="transactionAction" method="list">
			<result name="success">/transactionlog.jsp</result>
			<result name="input">/transactionlog.jsp</result>
		</action>
	</package>

 

JSP页面代码如下:

	<script language="javascript" >
	function disptime(){
	var now=new Date();
	
	var year=now.getFullYear();
	var month=now.getMonth()+1;
	var date=now.getDate();
	var hour=now.getHours();
	var minute=now.getMinutes();
	var second =now.getSeconds();
		document.getElementById("datetime").value=year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second;
		//year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second;
		setTimeout("disptime()", 1000);
	}
	
	function withdrawal(){
		var money=document.getElementById("trMoney").value;
		if(money.length>0){					
			if(!(money.search(/^[\+\-]?\d+\.?\d*$/)==0))
			{
				document.getElementById("errormoney").innerHTML="含有非法字符";
				return false;
			}else
			{
				if(parseFloat(money)<=0)
				{
					document.getElementById("errormoney").innerHTML="金额必须大于0";
					return false;
				}
				return confirm("确认取款吗?");
			}				
		}else {
			alert("金额不能为空!");
			return false;
				
		}
	}	
</script>
  </head>	
  <body onload="disptime()">
	<form  method="post" name="myform" action="/netbank/transaction/withdrawal" onsubmit="return withdrawal()">
		<div align="center">
		<table width="400" border="0" class="table">
			<tbody>
				<tr>
				<td width="100"> 取款时间:</td>
				<td><input type="text" name="log.datetime" id="datetime"></td>
				</tr>
				<tr>
				<td> 取款金额:</td>
				<td>
					<input type="text" name="log.trMoney" id="trMoney" ><!-- value="${log.trMoney} -->
					<span id="errormoney" style="color:red;"></span>
				</td>
				</tr>
				<tr>
				<td> </td>
				<td> <input type="submit" value="取款" /> 
				<span style="color:red;"> 	
		   		<s:fielderror/>       		 
	    		</span> </td>				
				</tr>
			</tbody>
		</table>	

出现的问题是:在部署好以后,正确的存款、取款都能完成,但是如果取款额超过当前余额时,取款验证没通过,页面显示错误信息,但当再次重新输入小于余额的数再提交时,还是不能完成正常跳转,依旧显示验证未通过的信息“您的账户余额不足!”,再执行存款时,无论输入大于余额还是小于余额的值都显示“您的账户余额不足!”,就好像是如果取款时的操作金额超过余额,之后无论再重新执行什么其它操作都会走取款的验证。

问题是ssh整合常见问题 ,因为struts2默认Action是多例的,也就是每次提交都会新建一个Action实例,那么第一次转账失败,不会影响第二次转账, 但是struts2 整合 Spring后, Struts2 如果配置到Spring 就变成 单例的, 那么第一次转账失败, 信息就保存到Action 中, 第二次转账 即使数据正确,也会出现 第一次错误, 因为Action 单例,没有去除之前的错误信息

解决方案: 在spring 中配置Struts2 的Action  scope="prototype"

我之前用的是Spring的注解方式,所以action是单例的

抱歉!评论已关闭.