Struts学习笔记:程序的组件设计与分析

根据上篇博客的工作原理,来看看一个具体的简单的小例子的分析,使用struts增加学生,如下图:

 

很简单的一个例子,源码下载:http://download.csdn.net/detail/duancanmeng/4517024,代码一看就懂,重要的是上面的思路要理清楚。

 

ActionForm据官方文档介绍应该归类到控制器

----------------------------------------------------------------------------------------------------华丽的分割线----------------------------------------------------------------------------------------------------------------

关于Action要注意的问题:

1,Action什么时候初始化?

    是在用户发出该Action请求时候,而不是在读取配置时初始化。

 

2,初始化几次?

    总共初始化一次,在用户第一次请求时候,不论struts-config.xml中有多少action的type都指向该action类,都只会初始化一次。

 

3,如果有两个Action的配置中的type都指向同一个action,action只初始化一次,也就是说多个action请求进入了同一个action类,这样容易造成线程安全问题,如何解决?

    *    如果这个信息只是用于某一个请求的,这个时候我们就不能用实例变量或者类变量;相反,如果我所有的请求刚好又需要共享某个信息,就可以用实例变量或静态变量来保存

    *    存取其他资源(javabean,session等)必须同步,如果这些资源需要保护的话。

    *    struts与struts2的区别,action安全和不安全是很大的一点

    *    来看一个简单例子:统计一个action访问次数,安全性问题的产生和解决图示:

 

----------------------------------------------------------------------------------------------------华丽的分割线----------------------------------------------------------------------------------------------------------------

ActionMapping——>对struts-config中<action-mapping>的封装

----------------------------------------------------------------------------------------------------华丽的分割线----------------------------------------------------------------------------------------------------------------

ActionForward(导航器)

redirect:

    False——>容器内跳转.RequestDispatcher:forward

    True——>容器外跳转.HttpResponse:sendRedirect   .跳转时需要带上绝对路径,例如 path=http://www.baidu.com

----------------------------------------------------------------------------------------------------华丽的分割线----------------------------------------------------------------------------------------------------------------

ActionForm的工作原理:处理ActionForm的一般步骤

1、检查Action映射,确定Action中已经配置了对ActionForm的映射

2,、根据name属性,查找formbean的配置信息

3、检查Action的formbean的使用范围,确定在此范围下(request,session),是否已经由此formbean的实例

4、假如当前范围下,已经存在了此formbean的实例,而且对当前请求来说,是同一种类型的话,那么就重用

5、否则,就重新构建一个formbean的实例(调用构造方法),并且保存在一定作用范围

6、formbean的reset方法被调用

7、调用对应的setter方法,对状态属性赋值

8、如果validate的属性设置为true,那么就调用formbean的validate方法

9、如果validate方法没有返回任何错误,控制器将ActionForm作为参数,传给Action实例的execute方法并执行

注意:直接从ActionForm类继承的reset和validate方法并不能实现什么处理功能,所以有必要自己覆盖。

 

由图也可以看出,验证在赋值之后,execute方法之前执行。

分析上面的流程图中,如何来证明form存了进去?在scope.setAttribute(name,form)处

1、从过程看:实现监听,进行监视

    HttpSessionAttributeListener

    ServletRequestAttributeListener

    上面两个接口分别可以捕捉到scope为request和session不同情况的属性动态

public class AttributeListener implements HttpSessionAttributeListener,
		ServletRequestAttributeListener {

	@Override
	public void attributeAdded(ServletRequestAttributeEvent arg0) {
		System.out.println("add request attribute");
		if(arg0.getValue() instanceof ActionForm){
			System.out.println("this is request add mothed");
			System.out.println(arg0.getName()+","+arg0.getValue());
		}
	}

	@Override
	public void attributeRemoved(ServletRequestAttributeEvent arg0) {
		System.out.println("Removed request attribute");
		if(arg0.getValue() instanceof ActionForm){
			System.out.println("this is request Removed mothed");
			System.out.println(arg0.getName()+","+arg0.getValue());
		}
	}

	@Override
	public void attributeReplaced(ServletRequestAttributeEvent arg0) {
		System.out.println("Replaced request attribute");
		if (arg0.getValue() instanceof ActionForm) {
			System.out.println("this is request Replaced mothed");
			System.out.println(arg0.getName() + "," + arg0.getValue());
		}
	}

	@Override
	public void attributeAdded(HttpSessionBindingEvent arg0) {
		System.out.println("Add session attribute");
		if (arg0.getValue() instanceof ActionForm) {
			System.out.println("this is session Add mothed");
			System.out.println(arg0.getName() + "," + arg0.getValue());
		}
	}

	@Override
	public void attributeRemoved(HttpSessionBindingEvent arg0) {
		System.out.println("Removed session attribute");
		if (arg0.getValue() instanceof ActionForm) {
			System.out.println("this is session Removed mothed");
			System.out.println(arg0.getName() + "," + arg0.getValue());
		}
	}

	@Override
	public void attributeReplaced(HttpSessionBindingEvent arg0) {
		System.out.println("Replaced session attribute");
		if (arg0.getValue() instanceof ActionForm) {
			System.out.println("this is session Replaced mothed");
			System.out.println(arg0.getName() + "," + arg0.getValue());
		}
	}

}


我们这里只关心ActionForm

可以看到action的配置文件中:

<action path="/add" type="com.pccw.action.AddStudentAction" name="studentForm">
			<forward name="addsuccess" path="/addsuccess.jsp"></forward>
			<forward name="addfail" path="/addfail.jsp"></forward>
		</action>


这里的scope没有设置,缺省值为:session,所以我们可以看到当请求过来的时候打印的信息:

这是在session的add方法中监控到的。

 

2、从结果去看

    在execute中直接从request来得到actionForm,然后通过与execute中的参数form进行比较,会发现,这两个东西是同一个东西。

public class AddStudentAction extends Action{

	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		StudentForm studentForm = (StudentForm)form;
		StudentDao dao = new StudentDaoImpl();
		boolean isSave = dao.addStudent(studentForm);
		String returnKeyValue = "addfail";
		if(isSave) returnKeyValue = "addsuccess";
		
		StudentForm studentForm2 = null;
		String scope = mapping.getScope();
		if(scope.equals("request")){
			studentForm2 = (StudentForm) request.getAttribute("studentForm");
		}else{
			studentForm2 = (StudentForm) request.getSession().getAttribute("studentForm");
		}
		System.out.println(studentForm == studentForm2);  //一个是参数,一个是从request中获取的
		return mapping.findForward(returnKeyValue);
	}

}


打印结果我们可以看到:

打印结果为true,说明是同一个东西,不紧紧是内容相同,而且地址相同。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值