实现Action
Struts2中,action负责对用户请求的处理,因此它是整个应用的控制器,也是整个应用的核心。而对开发者来说,他们需要提供大量的action类。相对于struts1而言,struts2的浸入性更低,因为它的action无需继承任何父类或者接口,仅仅是一个普通的POJO(但是应该包括一个无参数的execute方法)。struts2通常直接使用action来封装http请求参数(可以理解为表单中的参数,如username,password等),因此在对应的action类中,应该提供这些属性。此外action里面的实例变量还可以封装处理结果。在下一个页面中使用s标签的property属性就可以输出结果(也可以使用更复杂的标签输出复杂的实例变量)。实际上系统不会区分哪个封装请求,哪个封装处理结果。
Action接口和ActionSupport基类
虽然action类无需继承任何类,无需实现任何接口,但是为了开发更规范,Struts2提供了一个Action接口。该接口定义了五个逻辑视图的字符串常量,以及一个execute方法。除此之外,Struts2还为Action接口提供了一个ActionSupport实现类。此类中定义了很多方法,其中常用的就是execute,它返回SUCCESS。因此如果我们直接继承ActionSupport类,则会大大简化开发。
Action访问Servlet API
Struts2中的action与servlet没有任何的耦合,因此我们可以单独地测试action。但是有的时候我们确实需要访问servlet的API。所谓的访问API,说白了就是要操作request,session,application。它们三个是JSP的内置对象,而servlet有三个接口代表它们三个。因此访问servlet API,就是操作这三个内置对象。在Struts2中我们可以通过ActionContext类来操作。使用方法是,首先使用ActionContext.getContext()获取ActionContext实例,然后使用getApplication、getParameters或者getSession得到application对象、request对象或者session对象。之后使用get或者put方法操作这些对象(对应于jsp或者servlet中的getAttribute或者setAttribute方法)。
//首先获得ac实例,通过它的方法就能操作Servlet API ActionContext ac=ActionContext.getContext(); //get方法能够返回request中的对应名字的参数。ac直接调用put跟get操作的都是request String password1=(String) ac.get("password"); ac.put("newpassword", "123"); //操作application和session都是需要先得到它们对应的Map对象然后再操作。 String password2=(String)ac.getApplication().get("password"); ac.getApplication().put("newpassword", "123"); String password3=(String)ac.getSession().get("password"); ac.getSession().put("newpassword", "123");
Action直接访问Servlet API
为了更直接地访问,Struts2提供了几个接口:ServletContextAware、ServletRequestAware与ServletResponseAware。实现这些接口的Action就能直接访问对应的API。举个例子,如果想得到request,只需要在Action中声明一个request变量,然后实现对应接口,将接口的参数赋给action中的request变量即可。
public class myaction extends ActionSupport implements ServletContextAware{ private String password; private HttpServletResponse response; private HttpServletRequest request; private ServletContext context; @Override public void setServletContext(ServletContext arg0) { // TODO Auto-generated method stub this.context=arg0; }
ServletActionContext是一个工具类,里面有一些静态方法,如getPageContext,getRequest,getResponse,getServletContext等。这中访问方法虽然方便,但是因为与Servlet有了耦合,因此不利于高层次的解耦。
private HttpServletResponse response; private HttpServletRequest request; private ServletContext context; private PageContext pagecontext; @Override public String execute() throws Exception { //这四个静态方法哪来直接用就行 response=ServletActionContext.getResponse(); request=ServletActionContext.getRequest(); context=ServletActionContext.getServletContext(); pagecontext=ServletActionContext.getPageContext(); return super.execute(); }
实现了action类之后,我们要告诉框架哪一个请求与哪一个Action对应,因此需要在struts.xml中配置。
Struts2使用包来管理action,result和interceptor。每个package元素只能配置一个包。package的name属性是引用该包的唯一标示。除此之外包还可以继承,继承多个父包中的所有配置(一般我们定义的包都要继承struts-default)。如果要继承其他的包,则extends属性必须是另一个包的那么属性。还有一种仅仅用于继承的抽象包,用abstract标识。
由于一个web应用中可能有必要含有多个名字一样的action,为了省略相同的action名字,同时也为了解决在大型项目中的action重名问题,引入了命名空间的概念。同一个命名空间中的action不能重名,而不同的命名空间可以有相同的名字。package用来管理action,而namespace用来访问区分action,命名空间是包的一个属性。namespace必须以/开头。
Struts2不支持为单独的Action设置命名空间,而是通过包指定namespace属性来为包下面的所有Action指定共同的命名空间。如果配置package时没有指定namespace属性,那么包下的所有Action处于默认的包空间下,即什么都不写的话,相当于namespace是""。当某个包指定了命名空间后,该包下所有的Action处理的URL应该是命名空间+Action名。由于struts.xml文件加载的时候是从上到下的顺序,所以父包应该在子包之前。
<package name="cmaction" extends="struts-default" namespace="/loginrelated"> <action name="rightuser" class="com.cm.example" method="execute" > <result name="success">/WEB-INF/aaa.jsp </result> <result name="error">/WEB-INF/error.jsp</result> </action> </package>
这里要注意result对应的视图资源,必须要以/开头。
Action的动态方法调用
如果希望一个表单中的两个按钮使用不同的action处理(它们都是submit按钮),则需要在按钮onclick的时候使用脚本改变form中的action属性。
使用onclick改变action属性的方法如下:
<script type="text/javascript" > function lalala(){ targetForm=document.forms[0]; targetForm.action="loginrelated/rightuser";} </script> <form action="loginrelated/rightadsgadsgadguseearr" method="post"> <input type="submit" value="click me" onclick="lalala()"/> </form>
通配符:使用通配符的话,能简化操作,极大地减少action配置的数量。对一个处理类,只需要配置一次就可以了。写法如下:
<action name="*lalala" class="com.cm.example" method="{1}"> <result name="success">/WEB-INF/aaa.jsp </result> </action>
默认action与action的默认处理类
<package name="cmaction" extends="struts-default" namespace="/loginrelated"> <default-action-ref name="default1"></default-action-ref> <default-class-ref class="com.cm.defaultaction"></default-class-ref> <action name="*lalala" class="com.cm.example" method="{1}"> <result name="success">/WEB-INF/aaa.jsp </result> </action> <action name="default1" class="com.cm.defaultaction"> <result>/WEB-INF/defaultpage.jsp</result> </action> </package>
注意:如果将defaultaction配置在默认命名空间里,那么它就能够作为所有请求的默认action。由于package继承了struts-default,所以默认的action
本文出自 “指尖轻飞” 博客,谢绝转载!
原文地址:http://mengcao.blog.51cto.com/9395052/1686687