Struts2框架是一个高度可扩展性的框架,框架的大部分核心组件,struts2并不是直接以硬编码的方式写在代码中的,而是以自己的IoC(控制反转)容器来管理框架的核心组件。struts2以可配置的方式来管理struts2的核心组件,从而允许开发者可以很方便地扩展该框架的核心组件。
struts2常量配置
可在如下五个地方配置常量:
struts-default.xml
struts-XXX-plugin.xml
struts.xml
struts.properties
web.xml
若在其中有相同的常量名字,则后面的值覆盖前面的值。
包配置
在struts.xml中使用<package>元素,可以有如下属性:
name属性是必须的
extends属性可选,用来继承某个包,继承某个包就意味着可以使用父包的拦截器,action等资源。
namespace可选的,指定命名空间
abstruact可选的,若值为true,则不能定义action
示例:
<package name="default" namespace="/" extends="struts-default"> <default-action-ref name="index" /> <global-results> <result name="error">/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="error"/> </global-exception-mappings> <action name="index"> <result type="redirectAction"> <param name="actionName">HelloWorld</param> <param name="namespace">/example</param> </result> </action> <action name="login" class="ch1.LoginAction"> <result name="success">/helloworld/welcome.jsp</result> <result name="error">/helloworld/login.jsp</result> </action> </package>
在定义包的时候可以指定namespace如namespace=“/abc”,则该包下的action的url应该为/abc/xxx.action,另外有个默认的命名空间,如果在指定的url下没有找到action则到默认命名空间下查找,如果还没找到,则抛出异常。
应注意,命名空间只有一个级别,如:对于a/b/c/xxx.action只会在a/b/c下找,而不会在a/b下找。
拦截器配置
拦截器是AOP思想的应用。拦截器的使用可以让action在处理之前,或者之后插入开发者自定义的代码。
通常,拦截器有以下用途:
权限控制:
跟踪日志:
跟踪系统性能瓶颈:记录执行action的时间,以便查看执行哪段代码费时
拦截器和拦截器栈都是在<interceptors>元素下定义,示例:
<interceptors> <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/> <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/> <!-- Basic stack --> <interceptor-stack name="basicStack"> <interceptor-ref name="exception"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> </interceptor-stack> </interceptors>
示例中<interceptor-ref>元素是使用了其他的拦截器或拦截器栈。
ActionSupport
ActionSupport是默认的action类,如果定义action时没有指定class属性,那么就使用这个类。它提供了校验,国际化支持,处理用户请求等方法,因此继承这个类来写自定义的action类会拥有它的功能。
在action中访问ServletAPI
可以通过ActionContext类来访问ServletAPI,如:
public String execute(){ ActionContext ctx = ActionContext.getContext(); Map<String,Object> servletcontext = ctx.getApplication(); Map<String,Object> session = ctx.getSession(); Integer counter = (Integer)servletcontext.get("counter"); if(counter == null){ servletcontext.put("counter",1);//类似于servletcontext.setAttribute() } else{ servletcontext.put("counter",++counter); } session.put("user",getUsername());//类似于session.setAttribute() ctx.put("user",getUsername());//类似于request.setAttribute() return ""; }
这种方式是间接访问,还有一种方法可以通过ServletActionContext直接访问,如:
HttpServletRequest request = ServletActionContext.getRequest();
public class AccessServletAPIAction implements ServletRequestAware{ private HttpServletRequest request; @Override public void setServletRequest(HttpServletRequest arg0) { // TODO Auto-generated method stub this.request = arg0; } }
action配置
以一个例子来说吧。
<action name="login" class="ch1.helloworld.LoginAction" method="login"> <result name="success" type="dispatcher">/helloworld/welcome.jsp</result> <result name="error" type="plaintext"> <param name="location">/helloworld/login.jsp</param> <param name="charSet">GBK</param> </result> </action>
plaintext:没有任何排版,就是单纯的字符
redirect:重定向请求,会丢失之前处理结果的信息
redirect-action:当重定向到另一个action时使用,其param可以有actionName和namespace,猜猜也知道应该写什么值吧。
另外,在action的属性中可以使用通配符,不说了。
模型驱动
把请求的参数封装成一个model,然后让action类持有这个model,这就是模型驱动。这个action类需要实现ModelDriven接口,例:
public class UserBean { private String name; private String pass; private String tip; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPass() { return pass; } public void setPass(String pass) { this.pass = pass; } public String getTip() { return tip; } public void setTip(String tip) { this.tip = tip; } }
public class LoginAction implements ModelDriven{ private UserBean user = new UserBean(); @Override public Object getModel() { // TODO Auto-generated method stub return user; } }
当action类抛出异常时,可以直接处理了,也可以抛出。struts2使用拦截器将抛出的异常映射到结果视图,然后转入相应的视图做处理,例:
<action name="login" class="ch1.helloworld.LoginAction" method="login"> <exception-mapping exception="java.lang.Exception" result="error"> <result name="success" type="dispatcher">/helloworld/welcome.jsp</result> <result name="error" type="plaintext"> <param name="location">/helloworld/login.jsp</param> <param name="charSet">GBK</param> </result> </action>
<global-results> <result name="error">/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="error"/> </global-exception-mappings>