struts2框架的工作机制:
* struts2框架提供了核心过滤器
* 核心过滤器的作用是拦截请求资源
*核心过滤器的生命周期:init(),doFilter(),destroy()
* 在struts2框架运行时,将加载底层提供的各种配置文件
* 启动tomcat容器时,执行核心过滤器的init()方法
* init()方法加载struts2框架底层提供struts-default.xml和struts.xml等文件
* 在拦截页面请求资源时,将执行加载完的各种配置文件,进行相关的处理
*当点击页面的请求连接时,执行核心过滤器的doFilter()方法进行拦截
*在doFilter()方法里执行init()方法加载完的struts-default.xml和struts.xml
struts2框架的工作流程:
* 把项目工程发布到tomcat上
* tomcat容器加载web.xml配置文件
* 由于在web.xml配置文件中,配置了struts2框架的核心过滤器,加载其核心过滤器
* 在struts2框架提供的核心过滤器,解析struts.xml配置文件
* 核心的过滤器可以拦截页面的请求资源,并在解析的struts.xml配置文件进行查找
*执行对应的类的对应的方法
* 然后通过执行对应类的对应方法的返回值,在解析的struts.xml配置文件找到对应的result类型
*进而转向到对应的页面
搭建struts2框架开发环境:
* 创建web工程
* 导入所需最少jar包
struts2-core-2.3.1.1.jar:Struts 2框架的核心类库
xwork-core-2.3.1.1.jar:Command模式框架,WebWork和Struts2都基于xwork
ognl-3.0.3.jar:对象图导航语言(Object Graph Navigation Language), struts2框架通过其读写对象的属性
freemarker-2.3.18.jar:Struts 2的UI标签的模板使用FreeMarker编写
commons-logging-1.1.x.jar:ASF出品的日志包,Struts 2框架使用这个日志 包来支持Log4J和JDK 1.4+的日志记录。
commons-fileupload-1.2.2.jar:文件上传组件,2.1.6版本后需要加入此文件
commons-io-2.0.1.jar:传文件依赖的jar包
commons-lang-2.5.jar:对java.lang包的增强
asm-3.3.jar:提供了字节码的读写的功能,包含了核心的功能,而其他的jar包都是基于这个核心的扩展.
asm-commons-3.3.jar:提供了基于事件的表现形式。
asm-tree-3.3.jar:提供了基于对象的表现形式。
javassist-3.11.0.GA.jar:代码生成工具, struts2用它在运行时扩展Java类
* 创建jsp页面
* 创建action类文件
* 实现struts2框架提供的action接口,重写execute()方法
*代码如下:
publicclass HelloWorldAction implements Action {
publicString execute() throws Exception {
System.out.println("HelloWorldAction*********** execute()");
return"success";
}
}
* 创建struts2框架的配置文件,配置文件名为"struts.xml":
<?xmlversion="1.0" encoding="UTF-8"?>
<!DOCTYPEstruts PUBLIC
"-//ApacheSoftware Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!--
页面的请求连接:/primer/helloWorldAction.action
package:包
* name:包名,唯一的,必选项,不能为空。用于被其他package继承。
* namespace:命名空间,唯一的,可选项,缺省的时候是"/"。页面的请求连接的前半部分。
*extends:继承。
* extends="struts-default":struts-default.xml是由struts2框架底层提供的。
-->
<packagename="primer" namespace="/primer"extends="struts-default">
<!--
action:
* name:action的名称,对应的是页面的请求连接的后半部分
*class:对应类的完整路径
-->
<actionname="helloWorldAction"class="cn.itcast.primer.HelloWorldAction">
<!--
result:结果类型
*name:返回的结果类型,对应的是执行类的方法的返回值
publicString execute() throws Exception {
System.out.println("HelloWorldAction*********** execute()");
return"success";
}
*后面的文本部分:要转向到的页面
-->
<resultname="success">/primer/success.jsp</result>
</action>
</package>
<!--<package name="aaa" namespace="/aaa"extends="primer">
<actionname="abcdAction" class="cn.itcast.action.abcdAction">
<resultname="success">/success.jsp</result>
</action>
</package>-->
</struts>
* 在web.xml配置文件中,配置struts2框架提供的核心过滤器:
<filter>
<filter-name>StrutsPrepareAndExecuteFilter</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>StrutsPrepareAndExecuteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
struts2框架的拦截器:
* 由于struts2框架提供的核心过滤器的作用:处理请求资源的各种问题,导致核心过滤器过于庞大。
* 根据"分离关注"的概念,自定义多个过滤器,让自定义的每一个过滤器只完成其中一个功能,核心过滤器只负责调用这些自定义过滤器。
* 自定义的过滤器定义为"拦截器",拦截器是struts2框架底层提供的。在struts2框架中主要工作都是由拦截器来完成。
* struts2框架提供的拦截器,定义在struts-default.xml配置文件中。
<interceptorname="alias"class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
<interceptorname="autowiring"class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
<interceptor name="chain"class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<interceptorname="conversionError"class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
<interceptor name="cookie"class="org.apache.struts2.interceptor.CookieInterceptor"/>
<interceptorname="clearSession"class="org.apache.struts2.interceptor.ClearSessionInterceptor" />
<interceptorname="createSession"class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
<interceptorname="debugging"class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor"/>
<interceptorname="execAndWait"class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
<interceptorname="exception"class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
<interceptorname="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"/>
<interceptorname="modelDriven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<interceptorname="scopedModelDriven"class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
<interceptor name="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
<interceptorname="actionMappingParams"class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
<interceptorname="prepare"class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
<interceptorname="staticParams"class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
<interceptor name="scope"class="org.apache.struts2.interceptor.ScopeInterceptor"/>
<interceptorname="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"/>
<interceptorname="tokenSession"class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
<interceptorname="validation"class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
<interceptorname="workflow"class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
<interceptor name="store"class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
<interceptorname="checkbox"class="org.apache.struts2.interceptor.CheckboxInterceptor" />
<interceptorname="profiling"class="org.apache.struts2.interceptor.ProfilingActivationInterceptor"/>
<interceptor name="roles"class="org.apache.struts2.interceptor.RolesInterceptor" />
<interceptorname="annotationWorkflow"class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor"/>
<interceptorname="multiselect"class="org.apache.struts2.interceptor.MultiselectInterceptor" />
* 实际上,struts2框架提供的拦截器,就是各个具体类来完成。
* struts2框架在struts-default.xml配置文件中,提供了拦截器栈。来存放声明好的拦截器。
*struts2框架使用拦截器栈,进而使用各种声明好的拦截器。
* 拦截器的特点:
<!--
interceptor-stack:拦截器栈
*拦截器栈里面存放的是上面声明好的拦截器
*struts2框架是通过使用拦截器栈,进而使用对应的拦截器
*拦截器栈相当于list集合,执行拦截器栈时,是按照存放拦截器的先后顺序来执行
-->
<interceptor-stackname="defaultStack">
<interceptor-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="fileUpload"/>
<interceptor-refname="checkbox"/>
<interceptor-refname="multiselect"/>
<interceptor-refname="staticParams"/>
<interceptor-refname="actionMappingParams"/>
<interceptor-refname="params">
<paramname="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-refname="conversionError"/>
<interceptor-refname="validation">
<paramname="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-refname="workflow">
<paramname="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-refname="debugging"/>
</interceptor-stack>
* 在struts-default.xml配置文件,定义了多个拦截器栈,那默认执行哪个拦截器栈?
<!-- 配置struts2框架运行时,默认执行哪个拦截器栈,defaultStack-->
<default-interceptor-refname="defaultStack"/>
<!-- 配置struts2框架运行时,默认执行哪个类 ActionSupport-->
<default-class-refclass="com.opensymphony.xwork2.ActionSupport" />
* 虽然struts2框架提供了很多拦截器,但是不能满足所有需求。所以,还需要自定义拦截器。
* 过滤器和拦截器的区别:
* 相同点:
* 都是起拦截作用
* 不同点:
* 使用范围:
* 过滤器:属于J2EE范畴,任何web工程都能使用
* 拦截器:属于struts2框架,离开struts2,拦截器就不能使用
* 完成的功能:
* 过滤器:只需要拦截页面的请求资源
* 拦截器:所有其他工作交给了拦截器来完成
* 执行顺序:过滤器——> 拦截器
struts2框架的基本配置:
* 关于struts2框架的页面请求路径:
*namespace+actionName+".action"
* 关于struts2对action的搜索顺序:
1.获得请求路径的URI,例如url是:
http://server/struts2/path1/path2/path3/test.action
2.首先寻找namespace为/path1/path2/path3的package,
如果存在这个package,则在这个package中寻找名字为test的action,
如果不存在这个package则转步骤3;
3.寻找namespace为/path1/path2的package,
如果存在这个package,则在这个package中寻找名字为test的action,
如果不存在这个package,则转步骤4;
4.寻找namespace为/path1的package,
如果存在这个package,则在这个package中寻找名字为test的action,
如果仍然不存在这个package,就去默认的namaspace的package下面去找名
字为test的action(默认的命名空间为空字符串“/” ),
如果还是找不到,页面提示找不到action。
* 在没有为action指定class的时候:
<!--
* 没有为action指定class:在struts-default.xml文件进行配置
* 配置struts2框架运行时,默认执行哪个类 ActionSupport
<default-class-refclass="com.opensymphony.xwork2.ActionSupport" />
* 没有为action指定执行的方法时,默认执行ActionSupport类下的execute()方法
publicString execute() throws Exception {
return SUCCESS;
}
* 没有为action指定返回类型,默认执行ActionSupport类下的execute()方法的返回值
-->
<actionname="actionNoClass">
<resultname="success">/primer/success.jsp</result>
</action>
* 如果找不到对应的action的时候:
* 会导致报错:404 there is no Action map for ...
* 在struts.xml文件进行配置:
<!-- 在找不到对应action的时候,配置默认执行的action -->
<default-action-refname="helloWorldAction"></default-action-ref>
*修改struts2框架的请求后缀名:
*在struts.xml文件中进行配置:
*<constant name="struts.action.extension" value="do,love"></constant>
*相关常量在struts2框架底层提供的default.properties资源文件定义的
*创建一个名为"struts.properties"资源文件进行配置:
struts.action.extension=go
*如果在struts.xml文件和struts.properties文件同时配置请求后缀名,struts.properties文件配置起作用的
*原因:如果常量在多个配置文件进行配置,struts2框架会有一个加载顺序:
*struts-default.xml
*struts-plugin.xml
*struts.xml
*struts.properties
*web.xml
* 在struts.properties资源文件中配置的一些常量:
*<!--
配置当修改国际化资源文件时,是否重新加载
*false:默认值,不重新加载
*true:重新加载
-->
<!--<constant name="struts.i18n.reload"value="true"></constant> -->
*<!--
当修改struts2框架的配置文件时,是否重新加载
*false:默认值,不重新加载
*true:重新加载
-->
<!--<constant name="struts.configuration.xml.reload"value="true"></constant> -->
*<!--
配置struts2框架的模式
*false:是指生产模式
*true:是开发模式,具有更多的调试信息
###includes:
###- struts.i18n.reload = true
###- struts.configuration.xml.reload = true
-->
<constantname="struts.devMode" value="true"></constant>
* 如果struts.xml配置文件过大时:可以自定义配置文件
*创建自定义的配置文件,一般一个模块一个自定义配置文件
* 将自定义配置文件引入到struts.xml配置文件中:
<includefile="cn/itcast/primer/struts_primer.xml"></include>
XMLCode By Object
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 页面的请求连接:/primer/helloWorldAction.action package:包 * name:包名,唯一的,必选项,不能为空。用于被其他package继承。 * namespace:命名空间,唯一的,可选项,缺省的时候是"/"。页面的请求连接的前半部分。 * extends:继承。 * extends="struts-default":struts-default.xml是由struts2框架底层提供的。 * 在struts框架底层提供struts-default.xml文件中声明了所有的拦截器和拦截器栈, 来处理各种需求。我们需要继承struts-defaulte.xml文件,进而使用这些拦截器来完成对应需求。 --> <package name="primer" namespace="/primer" extends="struts-default">
<!-- 在找不到对应action的时候,配置默认执行的action --> <default-action-ref name="helloWorldAction"></default-action-ref>
<!-- action: * name:action的名称,对应的是页面的请求连接的后半部分 * class:对应类的完整路径 --> <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction"> <!-- result:结果类型 * name:返回的结果类型,对应的是执行类的方法的返回值 public String execute() throws Exception { System.out.println("HelloWorldAction *********** execute()"); return "success"; } * 后面的文本部分:要转向到的页面 --> <result name="success">/primer/success.jsp</result> </action> <!-- * 没有为action指定class:在struts-default.xml文件进行配置 * 配置struts2框架运行时,默认执行哪个类 ActionSupport <default-class-ref class="com.opensymphony.xwork2.ActionSupport" /> * 没有为action指定执行的方法时,默认执行ActionSupport类下的execute()方法 public String execute() throws Exception { return SUCCESS; } * 没有为action指定返回类型,默认执行ActionSupport类下的execute()方法的返回值
--> <action name="actionNoClass"> <result name="success">/primer/success.jsp</result> </action> </package>
<!-- <package name="aaa" namespace="/aaa" extends="primer"> <action name="abcdAction" class="cn.itcast.action.abcdAction"> <result name="success">/success.jsp</result> </action> </package> --> </struts> |