truts分为两个主要版本,struts1和struts2,struts2是由webwork2发展而来的
1、Framework概念:将相同类型问题的解决途径进行抽象,抽取成为一个应用框架。这就是Framework。
Framework的体系提供了一套明确的机制,从而让开发人员很容易宽展和控制整个Framework开发上的结构;通常,Framework的结构中都有一个“命令和控制”组件(“command and control” component)
通过基于请求响应模式的应用Framework,基本上有如下几个表现逻辑结构组成:
- 控制器(Controller)——控制整个Framework中各个组件的协调工作。
- 业务逻辑层(Business Logic)——对Framework本身来说,这里仅仅只是概念和几个提供服务的基础组件,真正的实现与客户的业务逻辑接轨,还需要开发人员在Framework上再次扩展。
- 数据逻辑层(Data Logic ) ——绝大多数应用系统都需要涉及到数据交互,这一层主要包括了数据逻辑和数据访问接口
2、Struts有其自己的控制器(Controller),同时整合了其他的一些技术去实现模型层(Model)和视图层(View)。
Struts的概念和体系结构
Struts有一组相互协作的类、Servlet以及Jsp TagLib组成。基于Struts架构的web应用程序基本上符合JSP Model2的设计标准,可以说是MVC设计模式的一种变化类型。
3、MVC的概念,MVC结构图
MVC处理过程:
- 首先控制器接收用户的请求,并决定应该调用哪一个模型来进行处理。
- 然后模型根据用户请求进行相应的业务逻辑处理,并返回数据。
- 最后控制器调用相应的视图格式化模型返回的数据,并通过视图呈现给用户,
MVC的优点:
- 首先,最重要的一点是多个视图能共享一个模型。同一个模型可以被不同的视图重用,大大提高了代码的可重用性。
- 由于MVC的三个模块相互独立,改变其中一个不会影响其他两个,所以依据这种设计思想能构造良好的松耦合的构件。
- 此外,控制器提高了应用程序的灵活性和可配置性。控制器可以用来联接不同的模型和视图去完成用户的需求,这样控制器可以为构造应用程序提供强有力的手段
MVC的适用范围
- 使用MVC需要精心的计划,由于它的内部原理比较复杂,所以你需要花费一些时间去理解它。将MVC运用到你的应用程序,会带来额外的工作量,增加应用的复杂性。
- 但对于开发存在大量用户界面,并且业务逻辑复杂的大型应用程序,MVC将会使你的软件在健壮性、代码重用和结构方面上一个新的台阶。尽管在最初构建MVC框架时会花费一定的工作量,但从长远角度看,它会大大提高后期软件开发的效率。
4、JavaWeb应用结构的发展
- 阶段1:JSP是一个独立的、自主完成所有任务的模块
- 阶段2:JSP Model1
- 阶段3:JSP Model2
早期的Java Web应用中,JSP文件同时负责生成网页、控制到下一个网页的流程,以及负责业务逻辑,这给Web开发带来一系列问题:
–HTML 和Java 强耦合在一起,JSP 文件的编写者必须既是网页设计者,又是Java 开发者。
–可读性差。
–调试困难。
–不利于维护,更改业务逻辑或数据可能牵涉相关的多个网页。
Model1
Model2:
•JSP负责生成动态网页
•Servlet负责流程控制
•JavaBean负责业务逻辑
5、Struts与Web App的关系
–既然struts叫做webframework,那么其肯定主要基于web层的应用系统开发。按照J2EEArchitecture的标准,struts应当和jsp/servlet一样,存在于webcontainer一层
6、完全手动配置一个Struts程序
1)下载struts-2.3.14-all.zip,解压缩,四个文件夹:apps,示例,是.war;lib目录,库,struts依赖的一些包,库;docs,文档;src,源代码
2)myeclipse中创建一个web project
3)导入jar包,不能将解压出的lib目录下的Jar包都拷入项目的WebRoot/WEB-INF/lib下,多拷贝也能出问题,最小需求包有:commons-fileupload-1.2.2.jar、commons-io-2.0.1.jar、commons-logging-1.1.1.jar、ognl-3.0.6.jar、struts2-core-2.3.14.jar、xwork-core-2.3.14.jar、freemarker-2.3.19.jar
4)修改web.xml,添加struts过滤器:
在这里的filter配置就说明添加上了struts框架,所有的应用都纳入到了struts的管辖范围了。
5)在src目录下创建struts.xml文件,注意,我们的应用运行时访问的不是src目录下的这个struts.xml,而是WebRoot\WEB-INF\classes目录下的struts.xml,任何src目录下的东西,IDE(myeclipse)都会自动拷贝一份到WebRoot\WEB-INF\classes目录下,为什么不直接在WebRoot\WEB-INF\classes下建呢?因为在IDE中看不到classes目录。
创建好struts.xml后,从apps中的现有struts.xml中拷贝头几行,如下:
这时在写下面内容时,如果没有提示功能,可以这样解决:
a: 点击window – preferences – 搜索 catalog – add
b:选择key type为URI
c:key: http://struts.apache.org/dtds/struts-2.3.dtd 该文件是 struts.xml文件中的,复制即可
d:location: 对应的dtd文件,位于struts-core包中,解压开,指定相应位置,
如:D:\Struts2.1.6\soft\struts- 2.1.6 \lib\struts2-core-2.1.6\struts-2.3.dtd
6)做完以上配置启动服务器,会出现错误,根据错误提示,是缺少jar依赖包,添加了javassist-3.11.0.GA.jar、asm-3.3.jar、asm-commons-3.3.jar、commons-lang3-3.1.jar、commons-lang-2.4.jar、struts2-convention-plugin-2.3.14.jar后启动正常。
7)编写测试程序
一个登录页面login.jsp:
一个结果页面result.jsp
一个class:LoginAction
然后配置struts.xml
启动服务器,然后访问login.jsp,输入用户名密码提交直接就返回一个result页面。
一开始在配置struts.xml时,将action配置成如:
至此,手工配置一个struts2.3.14环境完成。
7、通过上面的例子,在struts中,重要的是struts.xml中的配置
由web.xml中的filter可知(url-pattern为 /*),所有的应用都要经过struts的filter,所以login.jsp提交的action,即aas也不例外,对于jsp提交的action,如果没有后缀,filter会自动加上.action后缀,即action="aas" 等同于action="aas.action"
过程,请求先被struts filter过滤器接收,然后查找struts.xml,找其中的action,通过name找到匹配的action,然后就进入这个action,就是执行action的class属性指定的类生成的对象来处理请求,这个例子就是com.cdtax.struts2.LoginAction,因为这个类有两个成员变量与页面表单中用户名、密码属性一样,会自动调用对应的get和set方法进行类成员变量设置,并且会将这个信息放到request作用域中,设置完后,执行execute()方法,执行完毕后,转到struts.xml的action的下一步,找到result的name值等于execute()返回值的那一标签,执行其标签内容,就是/result.jsp。
8、关于struts.xml中的package,也有继承的概念,extends属性,继承某个package,这里是struts-default,这个包在struts2-core-2.3.14.jar中,有一个struts-default.xml文件,这个文件定义了struts如何自动赋值、类型转换等,如果没有继承这个文件,struts就会出错。
9、生成struts的帮助文档:1)新建一个java project ;2)将struts-2.3.14-all\struts-2.3.14\src\core\src\main\java下的org拷贝到新建java project的src下;3)导入依赖的包,主要是struts-2.3.14-all\struts-2.3.14\lib下的包和tomcat的lib下的jsp-api.jar和servlet-api.jar,haiyou一个是velocity-tools-view-1.4.jar,导入后应该没有错误了;4)执行Myeclipse的project下的generate javadoc,生成帮助文档。
10、关于LoginAction类中成员变量的赋值,不是根据成员变量的名字来进行set,而是根据setXXX方法来进行赋值。实验:
将login.jsp中form加一个age:,LoginAction中增加private int age;并增加get和set方法,result中增加age:${requestScope.age },这是正常情况,login中输入后,点击提交,结果result.jsp显示出结果,现在将LoginAction中的private int age改为private int aaa,在result.jsp中增加${requestScope.aaa },修改LoginAction中setAge和getAge方法为:public int getAge()
{
return aaa;
}
public void setAge(int aaa)
{
this.aaa = aaa;
}
则再次操作,结果age依旧能够显示出来,而aaa则为空;
如果将login.jsp中的age input的name改为aaa,则结果为age:0,aaa为空,因为login.jsp虽然没有传递名字为age的属性,但是LoginAction中有getAge和setAge方法,根据其为int型,设置一个age变量,int没有默认为0,虽然login.jsp传递了一个aaa属性值对,因为LoginAction中没有相应的get和set方法,所以没有设置aaa变量,因此为空。
11、关于服务器启动时命令行提示:有这样三行提示xml的解析顺序
信息: Parsing configuration file [struts-default.xml]
2013-5-13 14:12:02 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
信息: Parsing configuration file [struts-plugin.xml]
2013-5-13 14:12:02 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
信息: Parsing configuration file [struts.xml]
可以看到先是解析了struts-default.xml,这就是struts的默认配置,也是我们自定义的struts.xml所extends的,然后是struts-plugin.xml,这是一些插件的配置文件,格式与struts.xml一样,最后是我们自己定义的struts.xml。