您好,欢迎访问三七文档
当前位置:首页 > 建筑/环境 > 工程监理 > ModelDriven和Preparable拦截器_尚硅谷_封捷
“玩转”Java系列—————————————————————————————1【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】ModelDriven和Preparable拦截器[友情提示:学习相关课程后使用此文档效果更佳]1提出问题1.1如果不使用ModelDriven和Preparable拦截器技术,Action类需要包含JavaBean中的业务属性,例如:1.2目标:将冗余代码抽取出来,把操作一个一个散列的属性变为操作一个对象——在这里就是封装了业务信息的领域模型:JavaBean,以实现模块化编程。2分析问题Action类与JavaBean中的属性代码重复,是冗余代码面向过程的实现方法“玩转”Java系列—————————————————————————————2【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】2.1当前的情况下,目标Action的实例对象会被压入值栈栈顶,params拦截器会将表单域中的值注入到目标Action(也就是栈顶对象)对应的属性中。2.2我们的需求就是:如何在params拦截器工作之前把JavaBean压入值栈栈顶?3解决问题3.1使用ModelDriven拦截器3.2使用方法:①让我们的Action方法实现com.opensymphony.xwork2.ModelDriven接口,如图所示:泛型参数指定所使用的JavaBean的类型“玩转”Java系列—————————————————————————————3【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】②实现TgetModel();方法[1]首先在Action类中声明一个JavaBean的引用[2]创建一个JavaBean的实例对象,在getModel()方法中返回3.3修改Action类删除冗余代码,修改Action方法add()方法:update()方法delete()方法“玩转”Java系列—————————————————————————————4【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】edit()方法原因分析:①ModelDriven拦截器工作之后,Action类中的JavaBean和值栈栈顶的JavaBean指向的都是getModel()方法返回的那个对象,如图所示:②执行edit()方法后,Action类中的JavaBean指向的就是从Dao中取出的对象,而此时值栈栈顶的对象指向的还是原来“玩转”Java系列—————————————————————————————5【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】那个对象,没有被注入从数据库中取出的数据,而表单回显依靠的是栈顶对象此时edit()方法正确的写法是:正确回显:“玩转”Java系列—————————————————————————————6【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】遗留问题:edit()方法过于繁琐,还停留在面向过程的实现方式。如何改进?4原理剖析4.1Struts2运行机制[该图片请放大查看]4.2拦截器和拦截器栈①打个比方:我们去医院体检,需要检查很多个项目,比如:测血压、胸透、做心电图、测身高、测体重、测肺活量等等,经历这一系列的检查后,最终才能拿到体检报告。在DefaultActionInvocation的调度下,各拦截器依次执行,然后再执行目标Action“玩转”Java系列—————————————————————————————7【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】这里体检的项目就相当于我们Struts2里面的拦截器,若干个拦截器组织在一起就是一个拦截器栈,最终的体检报告相当于目标Action。②在Struts2中,默认的拦截器栈是:struts-default.xml中定义的defaultStack,这里只列举了其中一部分interceptor-stackname=defaultStackinterceptor-refname=exception/interceptor-refname=alias/interceptor-refname=servletConfig/interceptor-refname=i18n/interceptor-refname=prepare/interceptor-refname=chain/interceptor-refname=scopedModelDriven/interceptor-refname=modelDriven/„„interceptor-refname=params„„/interceptor-stack4.3params拦截器params拦截器有两项功能①提交表单时将表单域中的值注入到栈顶对象对应的属性中②目标页面为表单时,将栈顶对象的属性回显到对应的表单“玩转”Java系列—————————————————————————————8【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】域中4.4ModelDriven拦截器getModel()方法是由谁来调用的呢?通过在getModel()方法内设置断点,以Debug模式运行项目发现:找到ModelDrivenInterceptor.intercept()方法:程序在这里停住发现调用getModel()方法的是这个方法“玩转”Java系列—————————————————————————————9【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】总体流程:5改进edit()方法5.1问题分析获取目标Action如果目标Action实现了ModelDriven接口获取值栈调用getModel()方法将返回值压入值栈,最后压入的值一定在栈顶“玩转”Java系列—————————————————————————————10【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】问题产生的原因是:在getModel()方法中将一个手动创建的空对象提供给ModelDriven拦截器,单调死板。5.2需求:当目标action方法是edit()时,将从数据库中取出的JavaBean压入栈顶,当目标action方法是add()、update()时将一个空的JavaBean压入栈顶5.3解决问题借助Preparable拦截器,为ModelDriven拦截器“准备”不同action方法所需要的不同JavaBean5.4Preparable拦截器使用方法:①Action类实现com.opensymphony.xwork2.Preparable接口②为不同的action方法声明专门的prepare方法“玩转”Java系列—————————————————————————————11【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】③修改StudentAction类代码[1]prepare方法[2]getModel()方法“玩转”Java系列—————————————————————————————12【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】[3]action()方法5.5Preparable拦截器工作流程5.6自定义prepare方法的命名格式有什么玄机?“玩转”Java系列—————————————————————————————13【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】5.7深情的呼唤:急需在prepare拦截器之前有一个params拦截器“玩转”Java系列—————————————————————————————14【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】5.8paramsPrepareParamsStack拦截器栈paramsPrepareParamsStack从字面上理解来说,这个stack的拦截器调用的顺序为:首先params,然后prepare,接下来modelDriven,最后再paramsStruts2.0的设计上要求modelDriven在params之前调用,而业务中prepare要负责准备model,准备model又需要参数,这就需要在prepare之前运行params拦截器设置相关参数,这个也就是创建paramsPrepareParamsStack的原因。配置方法在struts.xml文件中,package标签下添加default-interceptor-refname=paramsPrepareParamsStack/default-interceptor-ref5.9paramsPrepareParamsStack拦截器栈工作流程“玩转”Java系列—————————————————————————————15【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】5.10最终的工作流程“玩转”Java系列—————————————————————————————16【更多Java–Android资料下载,可访问尚硅谷(中国)官网下载区】6补充:如何取消prepare()方法的执行在struts.xml文件中action标签内配置:!--覆盖prepare拦截器的alwaysInvokePrepare参数值为false--interceptor-refname=paramsPrepareParamsStackparamname=prepare.alwaysInvokePreparefalse/param/interceptor-ref
本文标题:ModelDriven和Preparable拦截器_尚硅谷_封捷
链接地址:https://www.777doc.com/doc-3973178 .html