Struts2入门详解
什么是Struts2:
一种基于MVC模式的轻量级的web框架,它本质上相当于servlet。在MVC设计
模式中,Struts2作为控制器(controller)来建立模型与视图的数据交互。
Struts2以WebWork为核心,采用拦截器的机制来处理用户的请求,使得业务逻辑控制器
能够与ServletAPI完全脱离开。
优点:
1.项目开源 2.提供Exception处理机制 3.Result方式的页面导航,通过Result标签很方便的实现重定向和页面跳转。 4.简单,统一的表达式语言来访问所有可供访问的数据。 5.标准、强大的验证框架和国际化框架。 6.可减少页面代码的标签(Struts2特有的标签) 7.可拓展Struts2框架,比如自定义拦截器,自定义结果类型,自定义标签,为Struts2 定制需要的功能。
WEB层框架有一个特点:基于前端控制器模式实现的。
传统方式开发,一个请求对应一个servlet,这样会导致很多的servlet。而Struts2框架 将所有的请求都先经过一个前端控制器,前端控制器先实现框架的部分功能,剩下具体操作 要提交到具体的Action中。Struts2的前端控制器是由过滤器实现的,因为所有的请求都可以 被过滤器拦截,然后再过滤器中实现部分的功能。
Struts2的文件结构:
apps:官方的示例程序 docs:官方提供的文档:Struts2快速入门、Struts2的文档、API等 lib:存放Struts2的核心类库,以及Struts2的第三方插件类库。 src:Struts2框架对应的源代码。
Struts2基本的开发包:
asm-3.3.jar : 操作java字节码的类库 asm-commons-3.3.jar : 提供了基于事件的表现形式 asm-tree-3.3.jar : 提供了基于对象的表现形式 Struts2-core-3.0.jar : Struts2的核心类库 xwork-core-...jar : WebWork核心库,Struts2的构建基础。 ognl-3.0.jar : 对象图导航语言(Object graph Navigation language)框架通过它读取对象的属性。 freemarker-2.4.jar : Struts2标签模板使用的类库 javassist-3.1GA.jar :javascript字节码解释器 commons-fileload-1.3.jar : Struts2文件上传组建依赖包 commons-io-2.2.jar : Struts2与流相关的依赖包 commons-lang-2.4.jar :包含一些数据类型工具,是对java.lang包的增强。 log4j-api-2.2.jar : 日志管理组件依赖包的api log4j-core-2.2.jar : 日志管理组件依赖包
Struts2开发:
1.创建一个页面
<h1>开发第一个Struts2案例</h1><a href="${pageContext.request.contextPath }/Struts2Demo1.action">点击请求Struts2的action</a>
点击链接,提交请求到服务器对应的action。
2.编写Action来处理请求
public class Struts2Demo1{
/**
* 提供一个默认的执行的方法:execute
* 公有的、返回值为String 类型 且方法没有任何参数
*/
public String execute(){
//这里只是执行了action的execute方法,并没有跳转页面
System.out.println("请求被Struts2Demo1这个action中的execute方法执行!");
return null;
}
}
3.配置action,让Struts2框架识别它是一个Action
Struts2的配置文件:源目录下 struts.xml配置如下:
<struts>
<!-- name属性值理论上随意,namespace体现在请求路径上
extends 说明其继承struts-default这个包,可以继承其中所有的配置
struts-default这个包在struts-default.xml中定义。
-->
<package name="demo" namespace="/" extends="struts-default">
<!-- 配置action name属性值:与请求路径${pageContext.request.contextPath }/Struts2Demo1.action相关-->
<action name="Struts2Demo1" class="action的全路径名称">
</action>
</package>
</struts>
4.在web.xml中配置前端控制器,由过滤器实现 StrutsPrepareAndExecuteFilter
配置如下:<!-- 配置Struts2 核心过滤器,前端控制器-->
<filter>
<filter-name>Struts2</filter-name>
<filter-class>org.apache.Struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
处理请求,进行页面跳转:
action中处理的方法需要返回一个String类型的值,就是一个逻辑视图(真实的页面的别名)
在struts.xml配置文件中可以配置逻辑视图对应的真实页面。
action中的请求处理方法:
public String execute(){
System.out.println("请求被Struts2Demo1这个action中的execute方法执行!");
//success 就是一个逻辑视图
return "success";
}
struts.xml配置文件中对应真实页面:
<struts>
<package name="demo" namespace="/" extends="struts-default">
<action name="Struts2Demo1" class="action的全路径名称">
<!-- 配置结果页面的跳转(将逻辑名与真实页面对应)-->
<result name="success">/demo1/demo1.jsp</result>
</action>
</package>
</struts>
Struts2 的执行流程:
1.客户端发送请求 2.请求经过前端控制器(核心过滤器 StrutsPrepareAndExecuteFilter)中执行一组拦截器(拦截器会完成部分功能) 3.执行action 4.返回一个结果视图 5.根据Result的配置进行跳转 Struts2的配置文件加载顺序: 每次请求都会先经过核心过滤器,它有两个功能: 预处理:加载配置文件,对应的是过滤器中的init()方法 执行:用来执行一组拦截器完成部分功能,对应过滤器中的doFilter()方法
看下StrutsPrepareAndExecuteFilter的init()方法:
public void init(FilterConfig filterConfig) throws ServletException{
InitOperation init = new InitOperation();
Dispatcher dispatcher = null;
try{
FilterHostConfig config = new FilterHostConfig(filterConfig);
init.initLogging(config);
dispatcher = init.initDispatcher(config); //通过这个方法加载配置文件
init.initStaticContextLoader(config,dispatcher);
prepare = new PrepareOperation(dispatcher);
execute = new ExcuteOperation(dispatcher);
this.excludePatterns = init.buildExcludedOatternsList(dispatcher);
postInit(dispatcher,filterConfig);
}finally{
if(dispatcher != null){
dispatcher.clearUpAfterInit();
}
init.cleanup;
}
}
dispatcher = init.initDispatcher(config); //通过这个方法加载配置文件
查看该方法:
public Dispatcher initDispatcher(HostConfig filterConfig){
Dispatcher dispatcher = createDisptcher(filterConfig);
dispatcher.init();
return dispatcher;
}
其调用了Dispatcher的init方法,进入查看:
public void init(){
if(configurationManager == null){
configurationManager = createConfigurationManager(DefaultBeanSelectionProvider.DEFAULT_BEAN_NAME);
}
try{
//下面的代码就是加载Struts2的配置文件的
init_FileManager();
init_DefaultProperties();//加载Struts2的所有常量 default.properties
//加载struts-default.xml struts-plugin.xml struts.xml
init_TraditionalXmlConfigurations();
//加载用户自定义的struts.properties
init_LegacyStrutsProperties();
//加载用户配置的提供对象
init_CustomConfigurationProviders();
//加载web.xml
init_FilterInitParameters();
//加载标准对象
init_AliasStandardObjects();
}
}
加载顺序:
default.properties
struts-default.xml
struts-plugin.xml
struts.xml ---配置Action以及常量
struts.properties --配置常量
加载web.xml --配置核心过滤器以及常量
后加载的配置文件会覆盖先加载的配置文件中定义的常量
Struts2的详细配置:struts.xml 主要用来配置action和请求对应的关系
Struts2框架通过包(package)来管理核心组件:Action和拦截器。每个包就是多个Action、拦截器、拦截器
引用的集合。
<!-- name属性:必填,指定名称,改名称是被其他包引用的key
namespace属性:可选,定义该包的命名空间
extends属性:可选,指定该包继承哪个包。继承包可以继承包中定义的Action、拦截器等
abstract属性:可选,指定包为抽象包,抽象包不能有Action定义。
-->
<package name="" namespace="" extends="" abstract="false">
<!-- -->
</package>
namespace属性值 和Action标签中的name属性值共同决定访问路径。
<!--
name属性:必填,标识Action,指定访问路径
class属性:Action对应的Action类
method属性:可选,指定请求Action时调用的方法,默认为execute()
converter属性:可选,指定类型转换器的类
-->
<action name="" class="" method="" converter="">
<result name="" type="">真实页面</result>
<result name="" type=""> /redirect.jsp?username=${username}//如果要传递两个参数,中间用&代替&</result>
</action>
result结果类型(type属性): type 所有类型 :(在Struts2-core.jar/struts-default.xml中可以找到)
dispatcher(默认) :跳转页面(转发)
redirect : 重定向
redirectAction :重定向到Action
chain : 用来处理Action链
plainText ;显示源文件内容,如文件源码
freemarker :处理FreeMarker模板
httpheader :控制特殊http行为的结果类型
stream :向浏览器发送 InputSream 对象,通常用来处理文件下载,还可用于返回 AJAX 数据。
velocity :处理 Velocity 模板
xslt :处理 XML/XLST 模板
Struts2常量的配置:
大多在默认的配置文件中已经配置好,根据开发的需求,可能需要改动。默认的常量在org/apache/Struts2 路径下defalut.properties文件中
3种方式:
1.在struts.xml文件中利用 <constant>标签配置常量 (常用!!!)
<struts>
<!-- 设置默认编码-->
<constant name="struts.il8n.encoding" value="UTF-8"/>
<!-- 设置开发者模式-->
<constant name="struts.devMode" value="true"/>
</struts>
2.在struts.properties文件中配置常量
struts.properties是一个标准的properties文件,格式为key-value对
###设置默认编码
struts.il8n.encoding=UTF-8
###设置action的请求扩展名为action或者没有扩展名
struts.action.extension=action,,
### 设置不开启动态方法调用
struts.enable.DynamicMethodInvocation=false
3.在web.xml文件中通过<init-param>标签配置常量
<!-- 配置Struts2 核心过滤器,前端控制器-->
<filter>
<filter-name>Struts2</filter-name>
<filter-class>org.apache.Struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>struts.il8n.encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
Struts2分模块配置
<struts><!-- 包含模块配置文件-->
<!-- 不指定路径默认在src下时的方式-->
<include file="struts-shop.xml"/>
<include file="struts-user.xml"/>
<!-- 配置文件在具体包时的方式-->
<iinclude file="cn/scx/action/struts-common.xml"/>
</struts>