Struts2 第二讲 -- Struts2的入门
搭建struts2环境时,我们一般需要做以下几个步骤的工作:
- 第一步:创建javaweb工程(这个很废话有木有)
- 第二步:找到开发Struts2应用需要使用到的jar文件.(这个很白痴有没有)
到http://struts.apache.org/download.cgi#struts2514.1下载struts-2.x.x-all.zip,最新的版本为2.5.14。下载完后解压文件,开发struts2应用需要依赖的jar文件在解压目录的lib文件夹下。不同的应用需要的JAR包是不同的。下面给出了开发Struts 2程序最少需要的JAR。
- struts2-core-2.3.3.jar:Struts 2框架的核心类库
- xwork-core-2.3.3.jar:Command模式框架,WebWork和Struts2都基于xwork, (以前使用Struts2时版本很低2.3.3,那是xwork-core-2.3.3.jar和struts2-core-2.3.3.jar还是独立的jar包,2.5.14中没有xwork-core包,和struts2-core合并了)
- ognl-3.0.5.jar: 对象图导航语言(Object Graph Navigation Language), struts2框架通过其读写对象的属性
- freemarker-2.3.19.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-lang3-3.1.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类
- log4j-api-2.9.1.jar包 依赖包
如图:
少了一个log4j-api-2.9.1.jar包
- 第三步:创建jsp文件.test.jsp
<body>
入门的路径:<br>
测试Struts2带有参数:<a href="${pageContext.request.contextPath}/primer/helloWorldAction.action?username='zhangsanfeng'">helloWorld</a><br>
测试命名空间:<a href="${pageContext.request.contextPath}/primer/primer/helloWorldAction.action">helloWorld</a><br>
测试action:<a href="${pageContext.request.contextPath}/primer/helloWorldAction.action">helloWorld</a><br>
</body>
- 第四步:创建Action文件,用来控制页面和服务器之间的转发。
public class HelloWorldAction implements Action{
@Override
public String execute() throws Exception {
System.out.println("欢迎访问HelloWorldAction中的execute方法!");
return "success";
}
//自定义add方法
public String add(){
System.out.println("欢迎访问HelloWorldAction中的add的方法!");
return "success";
}
}
在这段代码中我们并没有继承ActionSupport,而是实现了接口Action(ActionSupport实现了Action接口),我们查看Action接口
public interface Action {
public static final String SUCCESS = "success";
public static final String NONE = "none";
public static final String ERROR = "error";
public static final String INPUT = "input";
public static final String LOGIN = "login";
public String execute() throws Exception;
}
这个接口中定义了几个常量和一个函数,这都是很有用的,常量是我们的返回结果,而函数是一个默认执行函数,后面我们做介绍.我们将代码扔改回继承ActionSupport类
HelloWorldAction extends ActionSupport
在ActionSupport类中,我们查看发现其中实现了execute(),
public String execute() throws Exception {
return SUCCESS;
}
注意:Struts2对Action类的操作,可以实现Action接口,也可以继承ActionSupport类(com.opensymphony.包下),但是也可以不继承因为struts-default.xml中
<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
这句话默认继承了ActionSupport类.
第五步:编写Struts2的配置文件,这个文件要求:
(1)必须放置到src下(即项目的classpath的根路径下)
(2)名称必须叫做struts.xml,不能叫做其他的名称
注意:我们这里先操作,操作完再讲,为啥子只能叫这个名,叫狗蛋.xml就不行,放在web-INF下就不行.
配置如下:
关于XML约束的解决办法:
XML是有约束的,约束我们可以从struts2-core-2.5.14.1.jar包下的struts-default.xml或者是struts-2.5.dtd下找到
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
问题2:解决不提示,我们在写struts.xml时,提示可以帮助我们书写并能避免错误,但有时候不提示,那么怎么解决呢?
解压struts2-core包,找到struts-2.5.dtd(我们可以将一些以后会用到的dtd统一放在一个文件夹下,便于查找.),在Eclipse中Window-preferences-XML-XML Catalog然后配置如下图:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!--
package包
* name:包的名称,在struts.xml中不允许出现重名,名称要求惟一,用作继承
* namespace:命名空间,表示访问URL的时候,是否通过命名空间访问,默认是/
* extends:表示继承,struts2要求所有的包必须继承struts-default,这样才能使用struts-default.xml文件中定义的返回类型和拦截器
-->
<package name="primer" namespace="/primer" extends="struts-default">
<!--
问题:如果请求的路径查找不到action的情况下,程序运行会抛出异常 ,可以通过配置当找不到action的情况下,会执行默认的action
-->
<!--指定默认的action引用,如果该包下没有对应action配置,则启用该配置-->
<default-action-ref name="helloWorldAction"></default-action-ref>
<!--
action: 指页面的URL连接的名称对应访问的Action类
* name:访问的Action的路径
* class:对应的类的全路径 配置:1:
如果不指定:class="cn.itcast.a_primer.HelloWorldAction"
如果没有为action指定class,默认是com.opensymphony.xwork2.ActionSupport
执行ActionSupport中的execute方法
配置2:
2>如果没有为action指定method,默认执行action中的execute() 方法。
ActionSupport的execute方法里面就一句话return "success";
如果指定method,会执行method中定义的方法
配置3:
如果没有指定result的name属性,默认值为success。
-->
<action name="helloWorldAction" class="cn.youric.you.one_primer.HelloWorldAction">
<!--
result:指访问Action类的方法返回值,对应跳转的页面
* name:Action类中方法的返回值
* <result>中的文本内容:表示需要跳转的页面
-->
<result name="success">/primer/success.jsp</result>
<result name="add">/primer/add.jsp</result>
</action>
</package>
</struts>
Result中还可以有一个属性type,result 元素的 type 属性负责指定结果类型. type 属性的值必须是在包含当前包或者是当前包的父包里注册过的结果类型. type 属性的默认值为 dispatcher
这里注意:
- 1) <package name="primer">表示Struts2 把各种 Action 分门别类地组织成不同的包. 可以把包想象为一个模块. 一个典型的 struts.xml 文件可以有一个或多个包
- 2) <package namespace=”/primer”>表示,其中namespace 属性是可选的, 如果它没有给出, 则以 “/” 为默认值. 若 namespace 有一个非默认值, 则要想调用这个包里的Action, 就必须把这个属性所定义的命名空间添加到有关的 URI 字符串里
- 3) <package extends="struts-default">表示package 元素通常要对 struts-default.xml 文件里定义的 struts-default 包进行扩展. 这么做了以后, 包里的所有功能就可以使用,这些功能包括在 struts-default.xml 文件里的结果类型和拦截器
- 4) <action name="helloWorldAction">表示:每个 action 都必须有一个 name 属性, 该属性和用户请求的servletPath 之间存在着一一对应关系,此时对应:
<a href="${pageContext.request.contextPath}/helloWorldAction.action">helloWorld</a><br>
- 5) <action class="cn.itcast.a_primer.HelloWorldAction">表示:其中action 元素的 class 属性是可选的. 如果没有配置 class 属性, Struts 将把 com.opensymphony.xwork2.ActionSupport 作为其默认值. 如果配置了 class 属性, 还可以使用 method 属性配置该类的一个动作方法. method 属性的默认值为 execute 。
- 6) <result name="success">表示result 元素的 name 属性建立 <result> 和 Action 方法返回值之间的映射关系。name 属性的默认值为 “success
- 7) <result name="success">/primer/success.jsp</result>表示result 元素的 type 属性负责指定结果类型. type 属性的值必须是在包含当前包或者是当前包的父包里注册过的结果类型. type 属性的默认值为 dispatcher
- 8) result 元素:<action> 的一个子元素, 它告诉 struts 在完成动作后把控制权转交到哪里. result 元素(的name 属性)对应着 Action 方法的返回值. 因为动作方法在不同情况下可能返回不同的值, 所以同一个 action 元素可能会有多个 result 元素
在struts2框架中使用包来管理Action,包的作用和java中的类包是非常类似的,它主要用于管理一组业务功能相关的action。在实际应用中,我们应该把一组业务功能相关的Action放在同一个包下。配置包时必须指定name属性,如果其他包要继承该包,必须通过该属性进行引用,注意:name名称是唯一 。包的namespace属性用于定义该包的命名空间。该属性可以不配置,如果不指定该属性,默认的命名空间为“/”
通常每个包都应该继承struts-default包, struts-default包是由struts内置的,它定义了struts2内部的众多拦截器和Result类型。而Struts2很多核心的功能都是通过这些内置的拦截器实现。如:从请求中把请求参数封装到action、文件上传和数据验证等等都是通过拦截器实现的。当包继承了struts-default包才能使用struts2为我们提供的这些功能。 struts-default包是在struts2-core-2.x.x.jar文件中的struts-default.xml中定义。 struts-default.xml也是Struts2默认配置文件。 Struts2每次都会自动加载 struts-default.xml文件。加载的过程通过过滤器实现的
包还可以通过abstract=“true”定义为抽象包,抽象包中不能包含action。
第六步:在web.xml中加入Struts2 MVC框架启动配置,过滤器,没有它struts2就不能启动struts.xml,struts2的功能也就无法实现。[服务器启动是先要加载web.xml中的配置文件的,我们的web服务,不在web.xml中配置,一切都是空谈]
<!-- 添加struts2的核心过滤器,这是struts2运行的核心 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
完成上面的操作我们下面来实践一下:项目启动报错,这是因为我们少倒入一个jar包log4j-api-2.9.1.jar,我们倒入重启服务器OK
初次完成一个struts2的入门后我们来探讨前面提的问题,struts.xml的命名和位置,为什么要固定,我们在web.xml中知道了对struts.xml文件加载使用到了一个类org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter《Eclipse ---->Navigate---->open Type》
我们在这个类中发现了一个初始化方法init,我们在init上面打断点流程如下:
在StrutsPrepareAndExecuteFilter函数中,有初始化方法
public void init(FilterConfig filterConfig) throws ServletException {
.........................
dispatcher = init.initDispatcher(config);
.....................................
}
InitOperations
public Dispatcher initDispatcher( HostConfig filterConfig ) {
Dispatcher dispatcher = createDispatcher(filterConfig);
dispatcher.init();
return dispatcher;
}
Dispatcher
public void init() {
.............................
init_TraditionalXmlConfigurations(); // [2]
...........................
}
private void init_TraditionalXmlConfigurations() {
String configPaths = initParams.get("config");
if (configPaths == null) {
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
....................................
}
private static final String DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml";
在web.xml配置struts2的过滤器,在过滤器启动的时候,加载;按照顺序加载了三个文件,struts-default放置返回类型和过滤器,第二个是插件,第三个是我们的struts.xml.从上面我们看出名称是不能变的,而没给出路径,也就意味着只能从src下找,路径也是不变的.
加载完成后文件中的配置放置到内存中
<package name="primer" namespace="/" extends="struts-default"> <action name="helloWorldAction" class="cn.itcast.a_primer.HelloWorldAction"> <result name="success">/primer/success.jsp</result>
</action>
</package>
这里要知道
- 1) 在struts1.x中,struts框架是通过Servlet启动的,而在struts2中,struts框架是通过Filter启动的。
- 2) 在StrutsPrepareAndExecuteFilter的init()方法中将会读取类路径下默认的配置文件struts.xml完成初始化操作。
- 3) struts2读取到struts.xml的内容后,是将内容封装进javabean对象然后存放在内存中,以后用户的每次请求处理将使用内存中的数据,而不是每次请求都读取struts.xml文件。
- 4) 过滤器启动后加载:使用init方法,初始化struts的各种xml文件和属性文件
Struts2 第二讲 -- Struts2的入门的更多相关文章
- c#委托事件入门--第二讲:事件入门
上文 c#委托事件入门--第一讲:委托入门 中和大家介绍了委托,学习委托必不可少的就要说下事件.以下思明仍然从事件是什么.为什么用事件.怎么实现事件和总结介绍一下事件 1.事件是什么:. 1.1 NE ...
- Struts2 第一讲 -- Struts2开发前奏
我们在学习Struts之前,先来复习一下Servlet,众所周知Servlet是JavaWeb的三大组件.我们发送一个请求,这个请求交给Servlet处理,Servlet将处理的结果返还给浏览器.每个 ...
- 【军哥谈CI框架】之入门教程之第二讲:分析CI结构和CI是怎么工作的
[军哥谈CI框架]之入门教程之第二讲:分析CI结构和CI是怎么工作的 之入门教程之第二讲:分析CI结构和CI是如何工作的大家好!上一节,我们共同部署了一个CI网站,做到这一点非常简单,但是,亲们, ...
- Struts2第二天
Struts2第二天 昨天: 1.Action的编写方式:实现Action接口.继承ActionSupport.自定义pojo作为action 2.action调用方法:默认的execute.meth ...
- SSH开发模式——Struts2(第二小节)
上一小节已经学会了如何去搭建Struts2的开发环境,该篇博客我们继续深入Struts2,了解Struts2框架的拦截器. 首先对我们在web.xml文件配置的过滤器进行一个源码的分析. 在Strut ...
- 《驾驭Core Data》 第二章 Core Data入门
本文由海水的味道编译整理,请勿转载,请勿用于商业用途. 当前版本号:0.4.0 第二章 Core Data入门 本章将讲解Core Data框架中涉及的基本概念,以及一个简单的Core Data ...
- 逆向课程第二讲,寻找main入口点
逆向课程第二讲,寻找main入口点 一丶识别各个程序的入口点 入门知识,识别各个应用程序的入口点 (举例识别VC 编译器生成,以及VS编译生成的Debug版本以及Release版本) 1.识别VC6. ...
- POI教程之第二讲:创建一个时间格式的单元格,处理不同内容格式的单元格,遍历工作簿的行和列并获取单元格内容,文本提取
第二讲 1.创建一个时间格式的单元格 Workbook wb=new HSSFWorkbook(); // 定义一个新的工作簿 Sheet sheet=wb.createSheet("第一个 ...
- Stanford机器学习---第二讲. 多变量线性回归 Linear Regression with multiple variable
原文:http://blog.csdn.net/abcjennifer/article/details/7700772 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归 ...
随机推荐
- java XML解析成Map
1.需要解析的文件.xml <?xml version="1.0" encoding="UTF-8"?> <request> <r ...
- SQL更新派工单数量=任务数量的
select b.FCommitQty '任务数量',a.FQty '派工数量',a.FSourceBillNo '派工单号',b.FBillNo '任务单号',a.FStatus '派工状态' fr ...
- Java集合一
java的集合类主要由两个接口派生而出:Collection && Map 这两个接口是集合框架的根接口 Collection----直接派生:Set(无序集合,元素不可重复) Lis ...
- c# 判断是否是DICOM文件
public bool isDicom(string filename) { FileStream fs = File.OpenRead(filename); ]; fs.Read(data, , d ...
- PAT 1056 Mice and Rice
#include <cstdio> #include <climits> #include <cstdlib> #include <vector> #i ...
- TR move up && TR move down
code display :: <!DOCTYPE HTML><html> <head> <link href="boo ...
- ref 和 out 的区别
ref和out都是C#中的关键字,所实现的功能也差不多,都是指定一个参数按照引用传递. 对于编译后的程序而言,它们之间没有任何区别,也就是说它们只有语法区别. 总结起来,他们有如下语法区别: 1.re ...
- sharepoint2007就地升级2010系列(一)2007概览
大家可能熟悉了sharepoint2010,熟悉了sharepoint2013,做了N多个项目,但是有没有做过从sharepoint2007升级或者迁移到sharepoint2010的项目呢?我们做实 ...
- sql server性能分析--执行sql次数和逻辑次数
目前在做一个项目优化时,想通过数据库层分析sql server系统性能,查了一下网上代码,修改了一下标题和DMVs代码,以下代码可以用来分析系统运行一段时间后,那些语句是系统忙的sql语句.做为参考. ...
- MSSQL的SQL语句独立执行消耗与线上执行消耗差异
环境: SQL Server 2012 疑问:同样的一条语句,使用Profile跟踪出来的消耗与单独拿出来执行的消耗存在非常大的差距 语句如下: declare @str nvarchar(max) ...