搭建struts框架应用程序
搭建struts框架应用程序
简介:struts是Apache组织的一个开源项目,采用MVC模式,能够帮助java开发者利用javaEE开发web应用程序。,让开发者可以把精力集中在业务逻辑的代码上来。这里介绍的是struts1.x版本,但是struts2的原理和架构是不一样的。
n Struts的控制器(Controller)由ActionServlet、Action、struts-config.xml组成。ActionServlet是struts的入口,所有的请求都会通过它来处理,然后由它来决定由相应的Action来处理请求。Action代表了一次动作,如用户注册,购买商品等,开发者的业务逻辑代码也会在这里添加。配置文件struts-config.xml是对整个struts的配置,包括ActionServlet应该将请求转发给哪个Action,Action处理完成以后,又该由哪个JSP文件作为响应等。
n Struts的模型(Model)主要由ActionForm来实现。它有一点像JavaBean,包含了若干可读可写的属性,用于保存数据,也有数据验证的功能。一般来说,一个Action会配备一个ActionForm。
n Struts的视图(View)主要由JSP来实现。JSP在显示的数据可以来自ActionForm,也可以是Action保存在作用范围(request,session,application)的数据。当然,使用Struts自带的标签库可以起到最大的简化作用。
使用Struts开发web应用程序以后,开发者的思维也需要做一些改变,Action、ActionForm和JSP是一个整体了,每一次http请求都需要三者协作完成。JSP代表用户可以看到的东西,ActionForm代表的是数据,Action代表的是业务逻辑。图1表示的是Struts的MVC的各个组成部分,以及它们之间是如何一起协调完成工作的。
一次典型的Struts请求时这样完成的:首先,有浏览器客户端发送请求,请求的地址,默认为以“.do”结尾。然后,ActionServlet接到请求以后,先根据struts-config.xml中的配置或者说是根据请求的路径和参数来判断由哪个Action来处理该次请求。等到Action处理完成以后,用常识execute()方法调用完成以后,Struts会根据该方法返回的ActionForward来判断由哪个JSP来作为最终的响应,该过程如图2表示。
开发人员大多时候只要完成配置文件和Action,将大多数的精力集中在Action中的业务逻辑实现上面。如果业务逻辑有改动,只需要修改Action即可,如果是显示上有变化,也只需要修改JSP,两者实现了松耦合,互不影响。
使用Struts框架开发web应用程序可以分为以下4个步骤:
(1)搭建Struts开发环境,主要包括必需的jar文件、web.xml的配置和创建struts-config.xml文件。
(2)实现Views,主要是创建JSP文件,可以使用Struts提供的标签库。
(3)实现Model,主要是创建和配置ActionForm类,它需要继承自Struts提供的ActionForm类,然后使用<form-bean>标签在struts-config.xml中进行配置。
(4)实现Controller,主要是创建和配置Action类,它需要继承自Struts提供的Action类,并实现execute()方法,然后使用<action>标签在struts-config.xml中进行配置。
注意:因为struts属于javaEE以外的第三方技术,所以使用Struts时,必须遵守Struts的相关规定。一些IDE(集成开发环境,如eclipse,netbeans)提供了图形化界面的工具,可以很方便的为web应用程序添加Struts环境,其实这些工具的功能本质上就是要介绍的几个步骤。
图1:Struts的MVC结构
图2:Struts处理请求的过程和工作原理
为Web应用程序添加Struts功能的具体步骤
(1)复制Struts所需的jar文件到Web应用的/WEB/lib目录下面。首先,需要从Struts的网站(地址: http://struts.apache.org/)下载完成的开发包,笔者使用的是1.2.9版本。从下载的zip文件中可以找到8个jar文件,将它们全部复制到需要整合Struts功能的Web应用下的WEB_INF/lib目录下面。
(2)在web.xml中配置ActionServlet。ActionServlet是所有Struts请求的入口,它本质上也就是一个Servlet,它的默认URL匹配方式为“*.do”,所有以“.do”结尾的URL都会由ActionServlet来处理,以下是一个示例配置:
...
<!-- 配置Actionservlet的Servlet -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<!-- 指定Struts的配置文件地址 -->
<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>details</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<!-- 配置ActionServlet的URL匹配 -->
<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>
<!-- 放置所有的ActionForm配置 -->
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings>
<!-- 放置所有的Action配置 -->
</action-mappings>
<!-- 配置资源文件的路径 -->
<message-resources parameter="xxx.xxx.xxx.ApplicationResources" />
</struts-config>
完成了以上的这些步骤以后,就可以在web应用程序中使用Struts开发应用了。
实现Views
就是制作JSP页面。JSP在Struts中的作用主要有两个:提供用户输入接口和展示数据。大多数网页都包含了两个方面的内容,一个是用户可以输入数据的接口,例如,文本输入框,下拉菜单,提交按钮等。另一方面,就是来自后台的数据展现,如商品列表、数据状态等。一般来说,Struts程序是不会让用户直接访问JSP文件的,而是通过Action的request中的属性(Attribute)。
另外,Struts为JSP提供了丰富的标签库,尤其是HTML标签库,让JSP的表单和ActionForm成为了一个整体,提交表单的时候可以自动填充ActionForm,响应的时候可以为表单的输入框自动添加数据。
实现Model
ActionForm充当的是数据层的作用,它为开发者保存数据带来了便利,尤其对于大型Web项目来说,一个页面可能会包含几十个甚至上百个输入框,如果开发者对每一个请求参数都通过request.getParameter()的方式来获取的话,工作量会非常大,而且不利于维护。有了ActionForm以后,它可以帮助开发者自动填充数据。而且,它还提供了一些数据验证的功能。
自定义的ActionForm需要继承自org.apache.action.ActionForm类,然后把需要添加的字段作为成员变量进行设置,并为这些成员变量加上setter和getter方法。一下为一个包含商品名称变量的ActionForm:
import org.apache.struts.action,ActionForm;
//定义ProductForm,继承自ActionForm
public class ProductForm extends ActionForm{
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
ActionForm定义完成以后,还需要在struts-config.xml中进行配置以后,才能供Action使用,使用标签为:<form-bean>,它包含form的名称name属性和类型type属性,示例代码如下:
<form-bean>
<form-bean name="productForm" type="com.throne212.javaweb.ch15.struts.form.ProductForm">
</form-bean>
实现Controller
Action代表了一次动作,逻辑代码、数据装填代码和请求转发代码都会放在Action中,它是Struts罪核心也是最重要的地方,程序员大多数时候接触的地方也会是它。
自定义的Action需要继承自org.apache.struts.action.Action类,而且需要覆盖它的execute()方法,当有请求指向该Action的时候,Struts会实例化该Action,再调用execute()方法,一下是execute()的完整定义:
public ActionForward execute(ActionMapping mapping,ActionForm form,HtpServletRequest request,HttpServletResponse response){
……
}
它包含四个参数,即ActionMapping,ActionForm,HttpServletRequest,HttpServletResponse。最后的两个参数与Servlet的请求和响应是完全相同的。ActionMapping指的是该Action映射的信息,通常会调用该对象的findForward()来转到下一个资源或视图JSP,该方法的参数即为下一个资源的名称,在struts-config.xml中通过<forward>进行配置。ActionForm参数也就是与Action匹配的ActionForm对象,它是一个超类,往往需要进行强制类型转换,通过<action>的name属性指定。以下是一个包含商品浏览和搜索的Action的示例代码(其中,Product代表一件商品)
package myaction;
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;
//定义ProductAction类,继承自Action
public class ProductAction extends Action{
//重载execute()方法。
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest request,HttpServletResponse response){
Product[] ps = new Product[10];
for(int i = 0; i<ps.length;i++){
ps[i] = new Product("测试商品"+i,"好东西!");
}
request.setAttribute("products",ps);//设置数据到request范围中。
return mapping.findForward("product");//转到商品展示页面
}
}
然后,可以在struts-config.xml中进行如下的配置:
...
<action-mappings>
<action path="/ProductAction" name="productForm" type="myaction.ProductAction">
<forward name="product" path="/demo.jsp"></forward>
</action>
</action-mappings>
...
注意:Action的path属性需要以斜线“/”开头,它代表以本应用为根目录。同样,<forward>标签的path属性,也是需要以斜线“/”开头的。
零散知识点:
如果始终让一个Action类代表一个动作的话,当有成千上万个动作的时候,就要写成千上万个Action类。其实,Struts针对对该问题提供了多种Action来解决问题,Struts一共提供了4种Action,分别是Action,DispatchAction,LookupDispatchAction和MappingDispatchAction:
n 普通的Action类,每一个动作就对应一个Action类,一般不提倡使用。
n DispatchAction类,需要从客户端提供一个特殊的参数,参数的值等于方法的名字。对于一般的表单提交行的动作,可以使用。
n LookupDispatchAction类,需要实现getKeyMethorMap()方法。适用于一个表单有多个提交按钮的情况。
n MappingDispatchAction类,尽管无需从客户端获取参数来决定调用哪个方法,但是需要在struts-config.xml中配置多个<action>标签。适用于客户端不方便传参,且动作不是太多的情况。