菜鸟学Struts2——Actions

  在对Struts2的工作原理学习之后,对Struts2的Action进行学习。主要对Struts2文档Guides中的Action分支进行学习,如下图:

1、Model Driven(模型驱动)

Struts2可以让开发者不必在需要接收很多参数的时候,在Action定义一系列的属性,或者定义一个类属性传参的时候使用className.fieldName的形式传值。使用Struts2的Model Driven需要打开Model Driven拦截器,不过这个拦截器(scopedModelDriven)默认是打开的,只要将自己的包继承“struts-default”包即可(<package name="..." extends="struts-default" namespace="...">)。

(1)利用模型驱动进行开发,Action需要实现ModelDriven接口,并重写getModel()提供泛型中的Model对象。

 1 package yaolin.core.action;
 2
 3 import com.opensymphony.xwork2.ModelDriven;
 4 import yaolin.core.entity.Person;
 5
 6 public class PersonAction implements ModelDriven<Person>{
 7
 8     private Person person = new Person();
 9
10     public String input() {
11         return "input";
12     }
13
14     public String index() {
15         return "index";
16     }
17     // 重写ModelDriven的getModel()方法并提供Model对象
18     @Override
19     public Person getModel() {
20         return person;
21     }
22     // UI getter 这里只是方便页面取值
23     public Person getPerson() {
24         return person;
25     }
26 }

(2)Model有两个属性(name、age),提供必要getter和setter。

 1 package yaolin.core.entity;
 2
 3 public class Person {
 4
 5     private String name;
 6     private int age;
 7
 8     public String getName() {
 9         return name;
10     }
11
12     public void setName(String name) {
13         this.name = name;
14     }
15
16     public int getAge() {
17         return age;
18     }
19
20     public void setAge(int age) {
21         this.age = age;
22     }
23 }

(3)创建编辑页面(input.jsp)和回显页面(index.jsp),访问input.action到input.jsp填写信息提交到person.action(index方法处理)到index.jsp回显。

input.jsp不需要参数名不需要使用person.name、person.age,直接使用name和age。

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html>
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>INPUT</title>
 8 </head>
 9 <body>
10 <!-- /person/... -->
11 <form action="person.action" method="post">
12     <input name="name">
13     <input name="age">
14     <input type="submit" value="to_index">
15 </form>
16 </body>
17 </html>

index.jsp直接获取person的值。

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html>
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>INPUT</title>
 8 </head>
 9 <body>
10 ${person.name} - ${person.age}
11 </body>
12 </html>

(4)修改struts.xml对访问路径进行路由

 1 <!DOCTYPE struts PUBLIC
 2     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 3     "http://struts.apache.org/dtds/struts-2.3.dtd">
 4 <struts>
 5     <package name="person" extends="struts-default" namespace="/person">
 6         <action name="person" class="yaolin.core.action.PersonAction" method="index">
 7             <result name="index">/index.jsp</result>
 8         </action>
 9         <action name="input" class="yaolin.core.action.PersonAction" method="input">
10             <result name="input">/input.jsp</result>
11         </action>
12     </package>
13 </struts>

(5)访问input.action填写信息并提交观察结果

如果没有Model Driven则需要在Action,定义两个属性name、age而不是person并提供getter和setter,或者定义person并提供getter和setter同时将页面参数名称改成person.name、person.age

2、Action Chaining (Aciton链)

Action链可以将一个请求经过多个Action处理,并保持Request中的参数,这个Redirect重定向有点区别,Action链可以将请求叫同一个namespace的action处理,也可以交给其他namespace的action处理,实现Action Chain需要将result的type设置成“chain”。

(1)修改Struts.xml添加chain.action,还是使用ModelDriven学习中的input方法来处理这个请求,将result的type设置成“chain”把请求交给namespace="/chain"的chain.action处理。

 1 <!DOCTYPE struts PUBLIC
 2     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 3     "http://struts.apache.org/dtds/struts-2.3.dtd">
 4 <struts>
 5     <package name="person" extends="struts-default" namespace="/person">
 6         <action name="person" class="yaolin.core.action.PersonAction" method="index">
 7             <result name="index">/index.jsp</result>
 8         </action>
 9         <action name="input" class="yaolin.core.action.PersonAction" method="input">
10             <result name="input">/input.jsp</result>
11         </action>
12         <action name="chain" class="yaolin.core.action.PersonAction" method="input">
13             <result type="chain" name="input">
14                 <param name="actionName">chain</param>
15                 <param name="namespace">/chain</param>
16             </result>
17         </action>
18     </package>
19
20     <package name="chain" extends="struts-default" namespace="/chain">
21         <action name="chain" class="yaolin.core.action.ChainAction" method="index">
22             <result name="index">/index.jsp</result>
23         </action>
24     </package>
25 </struts>

(2)创建ChainAction对请求进行再次处理,并对额外参数进行处理,结果还是回显在index.jsp页面中。ChainAction中将person的名字加上前缀“Chain:”同时将额外参数extras加到名字后面。

 1 package yaolin.core.action;
 2
 3 import com.opensymphony.xwork2.ModelDriven;
 4
 5 import yaolin.core.entity.Person;
 6
 7 public class ChainAction implements ModelDriven<Person>{
 8
 9     private Person person = new Person();
10     private String extra;
11
12     public String index() {
13                 // 修改person的name属性
14         person.setName("Chain : " + person.getName() + " " + extra);
15         return "index";
16     }
17
18     @Override
19     public Person getModel() {
20         return person;
21     }
22
23     // UI
24     public Person getPerson() {
25         return person;
26     }
27     // POI
28     public void setExtra(String extra) {
29         this.extra = extra;
30     }
31 }
32     

(3)访问input.action并带上name,age和额外参数extras:http://localhost/person/chain.action?name=yaolin&age=18&extra=chen观察结果

3、ActionEventListener (Action事件监听器)

Action事件监听器可以使开发者在Action创建的时候加入一些业务逻辑,或者在Action处理出错的时候进行处理。整个Struts应用ActionEventListener只要一个实例就可以了,设置成单例,使用ActionEventListener可以在struts.xml中配置bean,ActionEventListener需要实现ActionEventListener接口。

(1)编写自己的ActionEventListener,并重写prepare()和handleException()方法,在prepare()方法中为Action的extra设置值

 1 package yaolin.core.listener;
 2
 3 import com.opensymphony.xwork2.ActionEventListener;
 4 import com.opensymphony.xwork2.util.ValueStack;
 5
 6 import yaolin.core.action.ChainAction;
 7
 8 public class MyActionEventListener implements ActionEventListener{
 9
10     @Override
11     public Object prepare(Object action, ValueStack stack) {
12         if (action instanceof ChainAction) {
13             // 设置Action的extra值
14             ((ChainAction)action).setExtra("##ChainActionEventListener##");
15         }
16         return action;
17     }
18
19     @Override
20     public String handleException(Throwable t, ValueStack stack) {
21         if (t != null) {
22             System.err.println(t.getMessage());
23         }
24         return null;
25     }
26 }

(2)在Struts.xml中配置ActionEventListener,指定其类型为其实现的主要接口com.opensymphony.xwork2.ActionEventListener。其他配置沿用之前两个部分学习的配置。

 1 <!DOCTYPE struts PUBLIC
 2     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 3     "http://struts.apache.org/dtds/struts-2.3.dtd">
 4 <struts>
 5     <package name="person" extends="struts-default" namespace="/person">
 6         <action name="person" class="yaolin.core.action.PersonAction" method="index">
 7             <result name="index">/index.jsp</result>
 8         </action>
 9         <action name="input" class="yaolin.core.action.PersonAction" method="input">
10             <result name="input">/input.jsp</result>
11         </action>
12         <action name="chain" class="yaolin.core.action.PersonAction" method="input">
13             <result type="chain" name="input">
14                 <param name="actionName">chain</param>
15                 <param name="namespace">/chain</param>
16             </result>
17         </action>
18     </package>
19
20     <package name="chain" extends="struts-default" namespace="/chain">
21         <action name="chain" class="yaolin.core.action.ChainAction" method="index">
22             <result name="index">/index.jsp</result>
23         </action>
24     </package>
25
26     <!-- 配置ActionEventListener -->
27     <bean type="com.opensymphony.xwork2.ActionEventListener" class="yaolin.core.listener.MyActionEventListener"></bean>
28 </struts>

(3)直接访问/chain/chain.aciton不带参数,参数由ActionEventListener设置,观察结果

至此,Struts2中Guides的Action Tag学习了。

未完,待续。

时间: 2024-12-17 23:54:23

菜鸟学Struts2——Actions的相关文章

菜鸟学Struts2——零配置(Convention )

又是周末,继续Struts2的学习,之前学习了,Struts的原理,Actions以及Results,今天对对Struts的Convention Plugin进行学习,如下图: Struts Convention支持零配置进行开发,也就是约定约定优于配置的方式. (1)环境准备 使用Convention Plugin进行开发,需要引入struts2-convention-plugin,完整的pom.xml依赖如下: 1 <dependency> 2 <groupId>org.apa

菜鸟学Struts2——Struts工作原理

在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中需要用户实现的部分只有三个,那就是struts.xml,Action,Template(JSP),如下图: 2.3.31中的org.apache.struts2.dispatcher.ActionContextCleanUp已经被标记为@Deprecated Since Struts 2.1.3,2

菜鸟学Struts2——Interceptors

昨天学习Struts2的Convention plugin,今天利用Convention plugin进行Interceptor学习,虽然是使用Convention plugin进行零配置开发,这只是在Interceptor的使用上,定义Interceptor还是使用strutx.xml配置形式.Interceptors模块如下图: (1)编写Interceptor 自定义Interceptor可以实现com.opensymphony.xwork2.interceptor.Interceptor

菜鸟学SSH(十六)——Struts2内部是如何工作的

前面说完了Spring.Hibernate,很自然今天轮到struts了.struts的核心原理就是通过拦截器来处理客户端的请求,经过拦截器一系列的处理后,再交给Action.下面先看看struts官方的工作原理图: 图1 struts原理图 简单分析一下:首先客户端发来HttpServletRequest请求,传递给FilerDispatcher(ActionMapper是访问静态资源(struts的jar文件等)时用的,平时很少用),然后FilerDispatcher会为我们创建一个Acti

《跟菜鸟学Cisco UC部署实战》-视频课程-学习投资

有朋友,有学生,问到学习投资些什么,注意:投资可重复利用!就看你怎么用!!! 所以,我写下此博文,目的为了更方便学员学习! 一.在线培训(直播): 1. 学费: 8168元. (目前没开班,如果需要培训大纲,培训计划,请联系QQ:学无止境 3313395633 ) 2. 1条电话初装费 初装费:150元(大约)+31元/月,测试后可以,如果不用,请停机保号,停机保号:5元/月. 3. 1条宽带 默认大家都能上网,不用单独投资! 4. 语音网关 680元(老师为购买此组合,本课程中使用此组合! 一

菜鸟学jQuery源码(一)

整个jQuery是一个自调用的匿名函数: 1 (function(global, factory) { 2 if (typeof module === "object" && typeof module.exports === "object") { 3 module.exports = global.document ? 4 factory(global, true) : 5 function(w) { 6 if (!w.document) { 7

菜鸟学jQuery源码(前言)

前言 相信任何一名前端开发人员或者是前端爱好者都对jQuery不陌生.jQuery简单易用,功能强大,特别是拥有良好的浏览器兼容性,大大降低了前端开发的难度,使得前端开发变得“平易近人起来”.自从本人用了jQuery,顿时感觉到人生再也不是灰色的了,又能够快乐的工作了. 不过在每天码得飞起的同时,我也对jQuery充满好奇,所以也特意的去查了一下资料.现在网上和书店里面有非常多的资料对jQuery源码从各种角度进行解析,大多都是对jQuery进行总结.归纳从上往下的分析.不过本人作为一名刚毕业的

菜鸟学Java(十九)——WEB项目测试好帮手,Maven+Jetty

做WEB开发,测试是一件很费时间的事情.所以我们就应该用更简单.更快捷的方式进行测试.今天就向大家介绍一个轻量级的容器--jetty.j今天说的etty是Maven的一个插件jetty-maven-plugin,与Maven配合起来使用非常的方便,它的配置也非常的简单,下面我们就看看它怎么用吧! 在pom.xml 文件的<project>标签下加入如下代码: <build> <plugins> <plugin> <groupId>org.mort

菜鸟学SSH(十三)——Spring容器解析及简单实现

最近一段时间,"容器"两个字一直萦绕在我的耳边,甚至是吃饭.睡觉的时候都在我脑子里蹦来蹦去的.随着这些天一次次的交流.讨论,对于容器的理解也逐渐加深.理论上的东西终归要落实到实践,今天就借助Spring容器实现原理,简单说说吧. 简单的说,Spring就是通过工厂+反射将我们的bean放到它的容器中的,当我们想用某个bean的时候,只需要调用getBean("beanID")方法. 原理简单介绍: Spring容器的原理,其实就是通过解析xml文件,或取到用户配置的