Struts2
什么是框架,有什么用处:
- 框架 是实现部分功能的代码(半成品),使用框架简化企业级软件开发,提高开发效率
- 学习框架,清楚的知道框架可以做什么,还有哪些工作需要自己实现?
Struts 2是什么:
轻量级的MVC框架,主要解决了请求分发的问题,重心在控制层和表现层。低侵入性,与业务代码的耦合度很低。Struts2实现了MVC,并提供了一系列API,采用模式化方式简化业务开发过程。
-
简述
- Struts2 是一个非常优秀的MVC框架,基于Model2 设计模型 (servlet+jsp+javaBean)- Struts2 是一个非常优秀的MVC框架,基于Model2 设计模型 (servlet+jsp+javaBean)
- 由传统Struts1和WebWork两个经典框架发展而来
- xwork 为webwork的核心,提供许多核心功能
- 前端拦截机(interceptor)
- 运行时表单属性验证
- 类型转换
- 强大的表达式语言(OGNL-the Object Graph Navigation Language)
- Inversion of Control 反转控制器容器等
- Struts2是Apache产品
- Struts2只能在javaweb中使用
- struts2是web层框架,常见的web框架还有:
- springMVC
-
核心功能:
- 允许POJO(Plain Old Java Objects)对象 作为Action
- Action的execute 方法不再与Servlet API耦合,更易测试
- 支持更多视图技术(JSP、FreeMarker、Velocity)
- 基于Spring AOP思想的拦截器机制,更易扩展
- 更强大、更易用输入校验功能
- 整合AJAX支持
-
与Servlet对比:
- 优点: 业务代码解耦,提高开发效率
- 缺点:执行效率偏低需要使用反射、解析XML等技术手段;结构复杂,编程难度大
- Servlet:如果功能很多,需要创建很多的servlet,维护不便
action 默认执行 execute方法
servlet 默认执行 service方法
MVC思想概述
-
java web动态编程技术,经历了Model和Model2时代。
-
Model1时代:整个Web应用几乎全部由jsp页面组成,jsp页面接收处理客户端请求,对请求处理后直接做出响应,用少量的JavaBean来处理数据库连接访问等操作。Model1的局限性非常明显,jsp页面同时担任View和Controller两种角色,将页面表现和逻辑处理混杂在一起,代码重用性极低,增加了扩展和维护难度。
-
Model2时代:已经采用了MVC的设计。在Model 2架构中,Servlet作为Controller,负责接收用户请求,只包含控制逻辑,然后调用后端来进行具体的逻辑处理。最后转发到相应的jsp页面负责显示。
-
MVC由Model(模型),View(视图),Controller(控制器)组成。
-
javaWeb中的三层架构
-
表现层:MVC,struts2框架其实是对表现层的MVC作了优化
-
业务层:service
-
持久层:dao
-
不同框架实现MVC的方式:
Servlet实现方式:
Struts2 实现方式:
Struts2 的安装使用
a.下载Struts2的jar 包
-
Struts2的目录结构
-
apps:该文件夹包含了Struts2的示例应用,对初学者有用,war后缀表示web压缩文件
-
docs:包含了相关文档,快速入门,api文档等
-
lib : 包含了Struts2 的框架和核心类库,以及第三方插件类库
- 开发时,没必要全部导入jar文件
-
src 该文件夹包含了Struts的框架的全部源码
- core 为源代码
- xwork-core Struts底层使用了xwork的源代码
-
b.创建一个web工程
c.导入Struts2所需的jar包
- 因为只是示例程序,只需要导入Struts 2支持最小的包就可以了,对于添加的最小包网上各有各的说法,这里给出一个保险的方法。
- 解压刚才下载的压缩包struts-2.3.14-all.zip,在apps文件夹下有个struts2-blank.war包,打开它,到WEB-INF/lib目录下,如下图所示,即为所需的最小包。包含的包应该和具体的Struts版本有关。
- Struts2-core >> Struts的核心类库
- xwork-core >> Command模式框架,WebWork和Struts2都基于xwork
- ognl >> 对象图导航语言 Struts2框架通过其读写对象的属性
- freemarker >> Struts2的UI标签的模板使用FreeMarker编写
- common-logging >> ASF出品的日志包,框架使用这个包支持Log4J和JDK1.4+ 的日志记录
- commons-fileupload >> 文件上传组件,2.1.6版本后需要加入此文件
- commons-io >> 传文件依赖的jar包
- commons-lang >> 对java.lang包的增强
d.配置web.xml
- web.xml文件中配置前端控制器(核心控制器)—–就是一个Filter
- 目的:是为了让struts2框架可以运行。
- 过滤器配置
/*
, 但是struts2 默认处理.action结尾请求,分发到相应Action类
<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>
e.对Struts.xml进行配置
- 创建一个struts.xml配置文件 ,这个是struts2框架配置文件。
- 目的:是为了struts2框架流程可以执行。
- 名称:struts.xml
- 位置:src下(classes下)
<!--url 为 http://127.0.0.1/项目名称/命名空间/模块名称/业务方法-->
<!--1.这里的 name为模块名称,namespace为模块空间
2.访问的时候,namespace 下面必须可以访问到模块名称和业务方法-->
<package name="User" namespace="/User" extends="struts-default">
<!--action name为业务映射方法;class后面需要添加具体的地址,包括包名;method为执行该类 中的哪一个方法-->
<action name="sayhello" class="cn.lenks.action.HelloAction" method="say">
<!--result 默认为name="success",当返回值为name值时,跳转到结果页面-->
<result name="success">/success.jsp</result>
</action>
<!--若是没有写明方法,默认执行execute方法-->
<action name="login" class="cn.lenks.action.LoginAction">
<result>/success.jsp</result>
</action>
</package>
f.添加链接,测试
<a href="${pageContext.request.contextPath}/UserLogin/sayhello">sayhello</a>
g.Action 类
别名:业务处理器
-
必须提供无参构造器 :
- Struts2 在加载配置时,会检测action的无参构造器,当客户端请求action的时候,Struts2会通过反射创建Action对象,并且会调用无参构造器
-
必须提供execute方法?
- 如果action标签中,没有设置method,他默认执行execute方法,此时,必须提供此方法,除非自定义method选项
Struts2处理流程
- 创建过滤器 Filter–StrutsFilter
- 在web.xml中配置StrutsFilter
- 在StrutsFilter中完成拦截操作,访问Action中的方法,跳转到success.jsp页面
代码展示思路:
// 2.1得到资源请求路径
String uri = request.getRequestURI(); //---> /day01_Hello/Test
String contextPath = request.getContextPath(); // --->/day01_Hello
String path = uri.substring(contextPath.length()+1);// ---> Test
//2.2 使用path去Struts.xml中查找某一个<action name=path> 这个标签
SAXReader reader = new SAXReader();
// 得到struts.xml文件的document对象。
Document document = reader.read(new File(this.getClass().getResource("/struts.xml").getPath()));
// 查找<action name='hello'>这样的标签
Element actionElement = (Element) document.selectSingleNode("//action[@name='" + path + "']");
if (actionElement != null) {
// 得到<action>标签上的class属性以及method属性
String className = actionElement.attributeValue("class"); // 得到了action类的名称
String methodName = actionElement.attributeValue("method");// 得到action类中的方法名称。
// 2.3通过反射,得到Class对象,得到Method对象
Class actionClass = Class.forName(className);
Method method = actionClass.getDeclaredMethod(methodName);
// 2.4 让method执行.
String returnValue = (String) method.invoke(actionClass
.newInstance()); // 是让action类中的方法执行,并获取方法的返回值。
// 2.5
// 使用returnValue去action下查找其子元素result的name属性值,与returnValue做对比。
Element resultElement = actionElement.element("result");
String nameValue = resultElement.attributeValue("name");
if (returnValue.equals(nameValue)) {
// 2.6得到了要跳转的路径。
String skipPath = resultElement.getText();
// System.out.println(skipPath);
request.getRequestDispatcher(skipPath).forward(request,
response);
return;
}
}
Struts2 的流程分析和工具配置
-
流程分析
- 请求 => StrutsPrepareAndExecuteFilter 核心控制器 => Interceptors 拦截器(实现代码功能)=>Action 的execute方法 => 结果页面(Result)
- 拦截器在struts-default.xml 中定义
- 执行拦截器是defaultStack中引用拦截器
-
关于手动配置struts.xml文件中提示操作
- struts.xml 提示来自DTD约束,
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
- 如果可以上网,自动缓存dtd,提供提示功能
- 如果不上网,可以配置本地DTD功能
-
使用插件
struts2-config-brower-plugin-2.3.7.jar
- 提供在浏览器中查看Struts2 配置加载情况
- 解压的jar文件复制到WEB-INF/lib下
- 访问 http://localhost/struts2_day01/config-browser/index.action 查看 struts2配置加载情况
最后更新:2018.10.31