1,使用框架进行程序开发的意义在于:框架本身包含了各种思想,这些思想是前人为开发人员总结的,他们往往具有开发效率高、易维护、是程序开发更简单的特点。Struts实现MVC的思想,Hibernate实现了对象 与关系映射的思想,Sping则是依赖注入和面向切面编程的思想,他们都是全世界开发者智慧的结晶。也是众多框架中的佼佼者。
2,MVC模式:
在java web开发中有两种普遍的开发模式(模式1和模式2),模式1使用jsp+javabean技术将页面显示和业务逻辑分开,有jsp实现页面 的显示,javabean对象用来保存数据和实现业务逻辑。客户端直接向jsp发出请求,jsp作出相应响应,并调用javabean对象,所有的数据都通过javabean来处理,然后再返回jsp,有jsp生成最后的返回结果。
在模型1中,jsp往往会嵌入控制请求流程的代码和部分逻辑代码,如果把这部分代码提取出来,有一个单独的较色来承担(该较色也就是控制器),则此时就构成了模型2,。模型2就符合了MVC的设计模式,即模型-视图-控制器的模式。
3,MVC框架的web应用程序被分割成若干逻辑部件,使程序开发变得更加容易。它把各种对象按照功能的不同分割成了3部分,主要目的就是将各种对象的耦合度降到最低。被分割的3部分是模型、视图、控制器。
模型:代表了应用程序的数据和处理这些数据的规则。当模型发生变化时,他会通知视图,并为视图提供查询模型相关状态的能力。
视图:用来组织模型的内容,他从模型那里获得数据,然后展现给用户,这较色往往有jsp承担。
控制器:负责从客户端接受请求,并把这些请求转换成某种行为,这些行为往往有模型来实现,这些行为完成以后,在选择一个视图呈现给用户。
如果使用已有是的知识实现一个MVC框架的web应用程序的话,可以这样来实现,有servlet来充当控制器的角色,他接受请求,根据请求信息的不同,将他们分发给不同 的jsp页面来作为用户的响应,同时servlet还要实例化一个javabean对象,jsp就可以使用javabean的相关标签来得到javabean的数据。
采用模型2,可以将页面的显示、业务逻辑的处理和流程的控制很清晰的分离开来。jsp负责页面的显示,javabean负责业务逻辑的处理,servlet负责流程的控制。MVC模式使得web应用程序很容以维护和扩展。因为各个部件的功能不同可以有不同的人进行开发和维护。例如,美工专门负责jsp页面成分发挥他们的美术和设计才能,而程序编写人员负责业务逻辑的实现。
4,Struts基础:
Struts的控制器是有ActionServlet、Action、和Struts-config.xml组成。ActionServlet是struts的入口,所有的请求都回通过它来处理,然后让他决定让相应 的Action处理请求。Action代表了一次动作,如用户注册、购买商品。开发者的业务逻辑代码也会在这里添加;配置文件Struts-config.xml是对整个struts的配置,包括Actionservlet应该讲请求转发给那个Action,Action处理完成以后,又有哪个jsp文件作为响应等。
Struts的模型主要有ActionForm来实现。他有一点类似于javabean,包含了若干可读可写的属性,用于保存数据,也有数据验证的功能。一般来说一个Action回配备一个ActionFom。
Struts的视图主要有jsp实现。jsp中显示的数据可以来自ActionForm,也可以是Action保存在作用范围内(request、session、application)的数据。当然是用struts自带的标签库可以起到最大的简化作用。
使用struts开发web应用程序以后,开发者 的思想需要做一下改变,Action、ActionForm和jsp是一个整体了。每一次Http请求都会有他们三者的发现。jsp代表用户可以看到的东西,ActionForm代表的是数据,Action代表的业务逻辑。
一次典型的struts请求是这样完成的:首先由浏览器客户端发送请求,请求的地址,默认为以“.do”结尾。然后Actionservlet接收到请求以后,会根据请求的路径和参数来判断有那个Action来处理此次请求;等到Action完成以后,通常是execute方法调用完成以后,struts会根据返回的ActionForward来判断是有那个jsp来作为最终的响应。
以上就是struts最核心的设计思想,开发人员大多数时候只需完成配置文件和Action,将大多数的精力集中在Action里的业务逻辑实现上面。如果业务上有改动,只需修改Action即可,如果是显示上的变化,也只需修改jsp,两者实现了松耦合,互不影响。
Action的URL后缀是“.do”是Struts的一种惯例,一般情况下不会做修改,通过配置也可以使用其他后缀,如“.action”。
5,Struts开发的一般步骤:
(1)搭建开发环境:最简单的一种就是MyEclipse提供的工具直接添加。还有一种就是手动添加:具体步骤就是1,复制Struts所需的jar文件到web应用的“/WEB-INF/lib”目录下面。2,在web.xml里配置,ActionServlet。Actionservlet是所有Struts的入口,他本质就是一个servlet,它的默认URL匹配方式为“/*.do”,所有以“.do”结尾的URL都会有Actionservlet来处理,以下是一个示例配置:
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
3,创建Struts的配置文件struts-config.xml。一般来说,配置文件存放在web应用程序的“/WEB-INF/struts-config.xml”目录下,通过配置文件指定Struts包含哪些Action、ActionForm等。示例配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans>
<form-bean name="greetForm" type="com.insigma.struts.GreetForm"></form-bean><!-- 放置所有的ActionForm配置-->
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings>
<action path="/CreetAction" type="com.insigma.struts.CreetAction" name="greetForm"><!-- 放置所有的Action配置-->
<forward name="greet" path="/greet.jsp"></forward>
</action>
</action-mappings>
<message-resources parameter="com.insigma.struts.ApplicationResources" /><!-- 配置资源文件的路径-->
</struts-config>
(2),实现View-jsps:
jsp在struts中的两个作用:提供用户输入接口和展示数据。一般来说,不会让用户直接访问struts的jsp文件,都是通过Action进行转发,所以jsp表单数据一般来自ActionForm,而其他的动态数据一般来自于Action的request里的属性(Attribute);
Struts为jsp提供了丰富的标签库,尤其是Html标签库,让jsp和actionForm成为了一个整体,提交表单的时候可以自动填充ActionForm,响应的时候可以为表单的输入框自动添加数据,而对于其他的动态数据,可以使用struts的标签库,也可以使用JStl,是数据的展示非常简便。
(3),实现Modle-ActionForms:
ActionForm充当的是数据层的作用,他为开发者保存数据提供了方便,尤其对于大型的web项目来说,一个页面可能包含几十个甚至上百个输入框,如果开发者的每一个请求参数都通过request.getParameter()的方式获取的 话,工作量会非常大,而且不利于维护,有了ActionForm以后,他可以帮助开发者自动填充数据。而且,它还提供了一些数据验证的功能。
自定义的ActionForm需要继承org.apache.struts.action.ActionForm类,然后把需要添加的字段作为成员变量进行设置,并为这些变量加上set和get方法。
import org.apache.struts.action.ActionForm;
public class GreetForm extends ActionForm {
String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
ActionForm完成以后,还需要在struts-config.xml里进行配置以后,才能供Action使用。使用标签为<form-bean>,它包含form的名称、name的属性和类型type属性。
(4),实现Controller-Actions:
Action代表了一次动作,逻辑代码、数据装填代码和请求转发代码都会放在Action里,它是struts最核心最重要的地方。
自定义的Action需要继承自org.apache.struts.action.Action类,而且需要覆盖它的execute方法,当有请求指向该Action时,struts会实例化该action在调用execute()方法。
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
它包含4个参数:ActionMapping、ActionForm、HttpServletRequest、HttpServletResponse,最后的两个参数与servlet的请求和响应是完全相同的。ActionMapping指的是该action映射的信息,通常会调用该对象的findForward()方法转到下一个资源护或视图jsp,该方法的参数即下一个资源的名称,在struts-config.xml通过<forward>进行配置,他是一个超类,往往需要强制类型转换,通过<action>的name属性指定,
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class CreetAction extends Action {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html,charset=utf-8");
//转换成ActionForm
GreetForm gForm=(GreetForm)form;
//往请求范围内设置用户名属性变量
request.setAttribute("username",gForm.getUsername());
//返回名字为greet的view
return mapping.findForward("greet");
}
}
然后在struts-config.xml里进行设置。
(5),访问Action的URL:
struts的可操作元素往往是以Action为单元的,有多少Action,就代表了多少个可进行的动作。Action的URl与ActionServlet的配置是有关系的,默认的情况下,所有的Action是以“.do”结尾的。
6,Struts标签库::
(1),Bean常用标签库:
Struts的Bean标签库是为了访问jsp的javabean和他们的属性而设计的。它是对jsp的动作标签<jsp:useBean>的改进,让开发者更好的使用请求参数、请求头和cookie等信息。但是他和jstl、el有一些重复的地方。
尽管如此,有一个标签时struts特有的,那就是,<bean:message/>,它是用力啊嘟嘟资源文件数据的。有的时候,一些常用的常量,如错误描述、多语言文本等保存在struts的资源文件ApplicationResources.properties里面便于维护。但是定义一个javabean来访问这些数据显得有些多余,皆可以直接使用这个标签,非常的方便。
资源文件ApplicationResources.properties的内容是以键值对的形式书写的,中间以“=”隔开,key=value.在使用<bean:message/>的时候,只需要指定该标签的key属性即可,它对应的就是资源文件的左边的名称,然后该标签就会返回相应的文本值。
(2)html常用标签:
HTML标签库是Struts使用最多的标签库,它架起了jsp与Action和ActionForm的桥梁。它主要提供了大多数的表单元素即数据管理功能。他在标单方面表现的比jstl和el更优秀一些。如果要构建一个表单,Html标签库是目前最好的选择。
<html:form>是用来包含其他标签的,他的action属性的值,应该和struts-config.xml里面的<action>的path属性的值相同,也是以斜线开头。他们中的大多住都包含一个property属性,与ActionForm的属性相对应,也就是如果ActionForm有一个username属性,那么property也许写成username。
7,Struts的高级特性:
1,使用多种Action:
Struts针对不同的情况,除了原始的Action以外,还提出了DispatchAction、LookupDispatchAction、MappingDispatchAction,后面的三个都可以将多个action方法写在一个Action里面。
Struts的多种Action
名称 使用情况 使用简介
Action 普遍的action 直接使用即可
DispatchAction 表单包含多个参数时使用 需要从客户端接受一个参数,该参数的值对应方法的名称
lookupDispatchAction 表单包含多个提交按钮的时候 需要重载getKeyMethodMap()方法,返回参数与方法名之间的对应 @ 关系
MappingDispatchAction 客户端不便于传递参数时适用 需要配置文件的<action>标签的parameter属性,指定Action的方法@ 名称
(1),DispatchAction的实现类为org.apache.struts.actions.DispatchAction,他需要从客户端接受一个参数,该参数的值与方法名对应。Struts会根据struts-config.xml里面配置的<action>标签的parameter属性来获取请求参数,然后利用java的反射机制调用方法名与参数值相同的方法。这些方法的参数列表和返回类型与Action的execute()方法完全相同。使用DispatchAction大致可以分为以下几步:
1>自定义一个继承自DispatchAction的类。把需要对外的每个action动作写成一个方法。方法的参数列表和返回类型与Action的execute()方法完全相同。
2>在struts-config.xml里配置Action。与配置一个普通的Action差不多,只是需要多加一个parameter属性,一般为action或method,他指定了客户端需要传递的参数名。
3>为客户端表单添加一个隐藏的输入框,他的值为需要调用的方法名。如果http请求采用提交表单的形式,隐藏的输入框是最好的选择;若是通过url访问Action的话,则需要在url后面加上请求参数。
(2),lookupDispatchAction:的实现类是org.apache.struts.actions.lookupDispatchAction,它主要适合于一个表单里有多个按钮的情况。lookupDispatchAction也需要从客户端接受一个参数,但是参数的值与方法名的对应关系需要一个getKeyMethodMap()方法来确定,该方法返回一个Map,该Map的Key与Value与资源文件ApplicationResources.properties的key和value对应。使用lookupDispatchAction的步骤:
1》,自定义一个lookupDispatchAction类把需要对外的每个action动作写成一个方法,该方法的参数列表和返回类型与action的execute()方法完全相同。然后实现父类的getKeyMethodMap()方法,该方法返回的Map与资源文件的部分内容相对应。
2》在资源文件ApplicationResources.properties里定义按钮的名称
3》在struts-config.xml里配置Action。与普通的配置Action差不多,只需多家一个parameter属性,一般为action或method,他制定了客户端需要指定的参数名。
4》当客户端表单包含两个提交按钮时,用<bean:message>标签来定义按钮的value,并按钮的name为参数的名字。
(3),MappingDispatchAction:MappingDispatchAction:的实现类为org.apache.struts.actions.MappingDispatchAction.
它无需从客户端接收参数,直接通过struts-config.xml里的<action>的属性parameter指定方法名,客户端不许咬任何配置,使用起来就像一个普通的eAction一样。他的确定就是可能导致struts-config的配置非常长,因为每一个方法都需加一个<action>标签。尽管如此,他还是要比原来的Action要好一点,至少不需要写那么多的action类了,所以MappingDispatchAction:更适合直接通过url访问Action。使用MappingDispatchAction:的步骤:
1》定义一个继承自MappingDispatchAction:的类,把需要对外的每个action动作写成一个方法,该方法的参数列表和返回类型与execute()方法的完全相同。
2》在struts-config里配置该action,与一个普通的Action差不多,对于没一个方法会对应一个<action>标签,他们的path各不相同,另外,parameter属性的值就是一个方法名。
3》,客户端访问MappingDispatchAction的时候,无论是表单还是直接使用url,与普通的Action没有区别。
8,使用多种ActionForm:
针对不同的情况,除了最原始的ActionForm以外,还提供了动态的ActionForm(DynaActionForm)和懒惰ActionForm(LazyValidatorForm)。在具体的开发过程中,可以有多种选择,如果数据量大或用途比较广泛,可以用普通ActionForm;如果数据量很小,则使用动态的DynaActionForm;如果数据量不太确定,那就是用懒惰的LazyValidatorForm
1》DynaActionForm的实现类为org.apache.struts.action.DynaActionForm,之所以称他为动态的ActionForm,是因为它是Action不比单独定义一个ActionForm类,而可以通过在配置文件里通过XML的形式定义ActionForm的字段及其类型。
此时的<form-bean>标签里的type属性应该是DynaActionForm的完整类名,然后再在其中嵌入<form-property>标签来定义属性,支持的数据类型包含8中java基本类型,String和时间类型。在Action的execute()方法和其他的action方法里。通过DynaActionForm.get()方法获取所需的参数。
2》lazyValidatorForm:
lazyValidatorForm的实现类是org.apache.struts.validator.lazyValidatorForm,他比起DynaActionForm来说更简单。lazyValidatorForm连用Xml定义字段的步骤都不必要了,他会自动将请求参数全部作为ActionForm的属性,所有的Action都可以使用它。只不过,对于使用lazyValidatorForm的Action在配置的时候,需要设置<action>标签的的validate属性的为false。
与DynaActionForm类似,在action的execute()方法或其他的action方法里。通过lazyValidatorForm.get()方法获取所需的参数。