struts.xml配置文件:
<struts>
<package name="default" extends="struts-default">
<action name="Logon"class="mailreader2.Logon">
<result name="input">/pages/Logon.jsp</result>
<result name="cancel" type="redirectAction">Welcome</result>
<result type="redirectAction">MainMenu</result>
<result name="expired" type="chain">ChangePassword</result>
</action>
</package>
</struts>
Struts是一个MVC框架,框架的controller在应用的model与web界面之间充当了连接的桥。
Struts2的标准标签库包含了一系列的Ajax JSP标签,它们可以完成很多工作,而我们只需要知道如何使用它们就行了。
依赖注入
性能分析,可以找到软件运行时的性能瓶颈。
可以这样在配置文件中配置:
<action ... >
...
<interceptor-ref name="profiling">
<param name="profilingKey">profiling</param>
</interceptor-ref>
...
</action>
页面翻译过于缓慢,有可能是freemarker的缓存被设置为了disabled,所以应该把一些缓存设置为enable并且把一些设置为disabled,如下:
<constant name="struts.devMode" value="true" />
<constant name="struts.i18n.reload" value="false"/>
<constant name="struts.configuration.xml.reload" value="false"/>
<constant name="struts.freemarker.templatesCache" value="true"/>
<constant name="struts.freemarker.templatesCache.updateDelay" value="120"/>
<constant name="struts.freemarker.mru.max.strong.size" value="120"/>
常量的查找是按照以下文件的顺序执行的:
1.struts-default.xml
2.struts-plugin.xml
3.struts.xml
4.struts.properties
5.web.xml
在web.xml中的常量配置如下:
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
<init-param>
<param-name>struts.devMode</param-name>
<param-value>true</param-value>
</init-param>
</filter>
属性:
name 必须且唯一
extends 非必须
namespace 非必须
abstract 非必须
如果package不指定namespace那么就是默认的namespace。
根namespace是“/”。
有如下配置:
<package name="default">
<action name="foo" class="mypackage.simpleAction">
<result name="success" type="dispatcher">greeting.jsp</result>
</action>
<action name="bar" class="mypackage.simpleAction">
<result name="success" type="dispatcher">bar1.jsp</result>
</action>
</package>
<package name="mypackage1" namespace="/">
<action name="moo" class="mypackage.simpleAction">
<result name="success" type="dispatcher">moo.jsp</result>
</action>
</package>
<package name="mypackage2" namespace="/barspace">
<action name="bar" class="mypackage.simpleAction">
<result name="success" type="dispatcher">bar2.jsp</result>
</action>
</package>
如上配置,如果请求为 /barspace/foo.action,那么会首先去barspace下寻找foo的action,如果没有找到,那么就会去执行默认的action,即name为default的package中name为foo的action。
使用标签来进行引入。被引入的文件必须与struts.xml保持一致的格式,包括DOCTYPE。
拦截器:name必须唯一
拦截器栈
大多数应用需要定义一个默认的拦截器栈。
action names
在action标签中,name可以设定为带有斜杠的形式,例如,如果需要这样设置,就需要如下设置常量,。
避免在action的name中使用点(.)和横杠(-),可能会造成不必要的麻烦。
action methods
自定义action必须实现action接口,并实现execute方法。
Struts默认执行execute方法,也可以在action的配置中指定特定的方法。但是如果没有指定相应的方法,action中也没有execute方法,那么就会抛出异常。
通配符
每个package都应该设置一个默认的结果类型,用于在没有指定结果时使用。如果一个package继承了另一个package,那么child package可以为其自己设置一个默认的result,当然也可以直接继承parent package的result。
Unkown Handler是实现了com.opensymphony.xwork2.UnknownHandler接口,当执行了未知的action,result或方法时被框架调用。
定义unkown handler需要在struts.xml中配置
<bean type="com.opensymphony.xwork2.UnknownHandler" name="handler" class="myclasses.SomeUnknownHandler"/>
配置多个unkown handler:
<bean type="com.opensymphony.xwork2.UnknownHandler" name="handler1" class="com.opensymphony.xwork2.config.providers.SomeUnknownHandler"/>
<bean type="com.opensymphony.xwork2.UnknownHandler" name="handler2" class="com.opensymphony.xwork2.config.providers.SomeUnknownHandler"/>
<unknown-handler-stack>
<unknown-handler-ref name="handler1" />
<unknown-handler-ref name="handler2" />
</unknown-handler-stack>
多个unkown handler将会按照unkown-handler-stack中配置的顺序执行。
web.xml
<web-app id="WebApp_9" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.mycompany.myapp.actions</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ... -->
</web-app>
如果需要支持应用服务器特定的文件系统,需要实现FileManager,并将其配置在web.xml中。参照DefaultFileManager.java和DefaultFileManagerFactory.java。
FileManager的配置:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>struts.fileManager</param-name>
<param-value>com.company.MyFileManager</param-value>
</init-param>
</filter>
FileManagerFactory的配置:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>struts.fileManagerFactory</param-name>
<param-value>com.company.MyFileManagerFactory</param-value>
</init-param>
</filter>
应用服务器的使用参照文档。
struts-default下默认的result与interceptor配置:
<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
<result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
</result-types>
<interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
<interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
<interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
<interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>
<interceptor name="cookieProvider" class="org.apache.struts2.interceptor.CookieProviderInterceptor"/>
<interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />
<interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
<interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
<interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
<interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
<interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
<interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
<interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
<interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
<interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
<interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
<interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
<interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
<interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
<interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
<interceptor name="datetime" class="org.apache.struts2.interceptor.DateTextFieldInterceptor" />
<interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
<interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
<interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />
<interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />
<interceptor name="deprecation" class="org.apache.struts2.interceptor.DeprecationInterceptor" />
某些默认拦截器继承了MethodFilterInterceptor,那么就可以通过传递参数(拦截action的方法名)来实现是否拦截此方法。例如:
<action name="myAction" class="myActionClass">
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">myValidationExcudeMethod</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">myWorkflowExcludeMethod</param>
</interceptor-ref>
</action>
继承了MethodFilterInterceptor的拦截器有:
拦截器方法:
ActionInvocation:可以通过ActionInvocation来获取到其他的action,由此可以调用其他action的方法。例如:
public class SimpleInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
MyAction action = (MyAction)invocation.getAction();
action.setDate(new Date());
return invocation.invoke();
}
}
Model Driven详解
action链可以如下配置使用:
<package name="public" extends="struts-default">
<!-- Chain creatAccount to login, using the default parameter -->
<action name="createAccount" class="...">
<result type="chain">login</result>
</action>
<action name="login" class="...">
<!-- Chain to another namespace -->
<result type="chain">
<param name="actionName">dashboard</param>
<param name="namespace">/secure</param>
</result>
</action>
</package>
<package name="secure" extends="struts-default" namespace="/secure">
<action name="dashboard" class="...">
<result>dashboard.jsp</result>
</action>
</package>
action最好只作为服务层来调用各个业务逻辑层的方法。
添加PreResultListener可以在拦截器或者action返回result之前执行一些逻辑。
action
public class MyAction extends ActionSupport {
...
public String execute() throws Exception {
ActionInvocation invocation = ActionContext.getContext().getActionInvocation();
invocation.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation invocation,
String resultCode) {
// perform operation necessary before Result execution
}
});
}
...
}
interceptor
public class MyInterceptor extends AbstractInterceptor {
...
public String intercept(ActionInvocation invocation) throws Exception {
invocation.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation invocation,
String resultCode) {
// perform operation necessary before Result execution
}
});
}
...
}