| |
model就是在对用户请求的整个控制过程中,真正处理用户请求并保存处理结果的对象,在整个过程中,我们一般利用javabean来把一些信息保存起来以便在各个对象之间传递。因为在框架中,model对象是真处理商业逻辑功能的对象,因此也就是框架中应用需求实现相关性最大的的部分。在struts的实现里,model的具体表现形式就是actionform对象和与其对应的action对象了。对用户提交表单的数据进行校验,甚至对数据进行预处理都能在actionform中完成。通常的应用中,一般是一个model对象和一个请求页面对应的关系,但也可以一个model对象对应多个页面请求。如果struts-config.xml配置文件没有指定一个model对象对应的action,那么控制器将直接把(通过model对象完成数据封装的)请求转到一个view对象。下图表示的是model layer 的层次结构。 在struts中model以一个或多个java bean的形式存在。这些bean分为三类:action form、action、javabean or ejb。action form通常称之为formbean,封装了来自于client的用户请求信息,如表单信息。action通常称之为actionbean,获取从actionsevlet传来的formbean,取出formbean中的相关信息,并做出相关的处理,一般是调用javabean或ejb等。 许多需求文档将构建web应用的焦点集中在视图上。我们必须确保每一个提交的请求都在模型视图中都已经被定义。通常,开发者在模型组件中关注于开发javabean类以实现所有的功能需求。 应用应该准确的使用哪些beans,根据其需求不同而差异巨大,但是,在经过区分后通常都能分被为若干个类别。 创建model 组件 1、javabeans 在一个web基础的应用中,能使用许多不同的"属性(attributes)"集合来保存(和访问)javabeans。 每个集合都有它自己不同的生命周期和beans存储在哪里的可见度。 同时,beans通过 作用域 来定义生命周期和可见度规则。 在javaserver pages (jsp)规范中定义了作用域选择使用以下几项(在括号中是servlet api中的等价概念定义)。 page :beans只会在一个jsp页中可见,只在当前的请求周期中存在。 (在 service 方法中的本地变量) request : beans只会在一个jsp页中可见,与page相同或servlet包含本页,或转发到本页。 (request属性) session :beans能被所有的jsp页和servlet通过特定的用户session来使用, 它可以跨越一个或多个请求。 (session属性) application :beans能被web应用中的所有jsp页和servlets来使用。 (servlet context属性) 我们需要记住的是在一个web应用中jsp页面和servlet会共享bean集合的设置。 例如在一个servlet中将一个bean存储到attribute中如下: mystudy mystudy = new mystudy(...); request.setattribute("cart", mystudy); 在这个servlet将请求转发给一个jsp页面后,我们马上可以使用标准的动作标签(tag)来看到相应的值: < jsp:usebean id="cart" scope="request" class="com.mycompany.myapp.mystudy"/ > 2、actionform beans 在 actionform beans频繁地有属性相当于属性在我们的model beans的时候,那form beans它们自己应该考虑成为一个控制器组件。 同样地,他们能在模型和视图层之间传递资料。 struts框架通常假定我们在我们的应用中已经为输入定义一个 actionform beans(简而言之,一个扩展自 actionform 类的java类)。 actionform beans有时仅仅调用表单beans(form beans)。 这可能会是一个细粒度的对像,它让每个表单对应一个bean,还有就是一个bean服务于若干个表单甚至全部应用形成粗粒度的情况。 如果在我们的struts配置文件中定义了bean,struts的controller servlet在调用适当的 action 方法前将自动为我们提供如下服务: 使用适当的关键字检查在用户适当的作用域(request或session)中是否有适当类的bean的一个实例。 如果没有这样的实例可用,则自动建立一个新的bean实例并将期加入到适当的作用域中(request或session)。 对于每个请求参数通过其名称来对应到bean的一个属性(property)上,并调用相应的setter方法来设置属性值。 这个方法类似于标准jsp中以以通配符"*"来使用 < jsp:setproperty > 标记。 更新后的 actionform bean被传递给 action 类[ org.apache.struts.action ] 的 execute 方法, 以使这些值能被我们的系统状态和业务逻辑bean来使用。 我们应该注意一个"表单(form)"在这里并不是必须对应于用户界面中一个单独的jsp页面。 在很多应用程序中一个"表单"(从用户的观点)延伸至多个页面也是很平常的。 想想看,例如,在新程序的安装时所使用的导航程序的用户界面。 struts鼓励我们定义一个包含所有字段属性的单独的 actionform bean, 而不用管这些字段实际显示于哪个页面上。同样的,同一表单的不同页面应提交到相同的action类。 如果我们遵照这个建议,在大多数情况下,页面设计者可以重新组织不同页面中的字段而不需要改变处理逻辑。 一个小的应用也许只需要一个actionform来为所有的输入表单提供服务。 其它应用可以为每个大的子系统来分别使用一个actionform。 还有一些人可能更喜欢为每一个输入表单或工作流分别使用不同的actionform类。 真正如何使用actionform完全在于我们,框架自身并不在意的。 actionform 接口本身不需要特殊的实现方法。它是用来标识这些特定的beans在整个体系结构中的作用。典型情况下,一个 actionform bean只包括属性的get方法和set方法,没有商业逻辑。 通常在一个 actionform bean中只有很少的输入验证逻辑。这样的beans存在的主要理由是保存用户为相关的表单所输入的大部分近期值,这样同样的页面可以被重建,伴随有一组出错信息,这样用户仅仅需要纠正错误的字段。用户输入的验证应该在 action 类中执行(如果是很简单的话),或者在适当的商业逻辑beans中执行。 为每个表单中出现的字段定义一个属性(用相关的getxxx()和setxxx()方法)。字段名和属性名必须按照javabeans的约定相匹配。例如,一个名为 username 的输入字段将引起 setusername() 方法被调用。 下面是actionform类的具体描述: actionform类 框架假设用户在应用程序中为每个表单都创建了一个actionform bean,对于每个在struts-config.xml文件中定义的bean,框架在调用action类的perform()方法之前会进行以下操作: 1、在相关联的关键字下,它检查用于适当类的bean实例的用户会话,如果在会话中没有可用的bean,它就会自动创建一个新的bean并添加到用户的会话中。 2、对于请求中每个与bean属性名称对应的参数,action调用相应的设置方法。 3、当action perform()被调用时,最新的actionform bean传送给它,参数值就可以立即使用了。 actionform类扩展org.apache.struts.action.actionform类,程序开发人员创建的bean能够包含额外的属性,而且actionservlet可能使用反射(允许从已加载的对象中回收信息)访问它。 actionform类提供了另一种处理错误的手段,提供两个方法: public actionerrors validate(actionmappin mapping,servletrequest request) public actionerrors validate(actionmappin mapping,httpservletrequest request) 我们应该在自己的bean里覆盖validate()方法,并在配置文件里设置<action>元素的validate为true。在actionservlet调用action类前,它会调用validate(),如果返回的actionerrors不是null,则actinform会根据错误关键字将actionerrors存储在请求属性列表中。 如果返回的不是null,而且长度大于0,则根据错误关键字将实例存储在请求的属性列表中,然后actionservlet将响应转发到配置文件<action>元素的input属性所指向的目标。 如果需要执行特定的数据有效性检查,最好在action类中进行这个操作,而不是在actionform类中进行。 方法reset()可将bean的属性恢复到默认值: public void reset(actionmapping mapping,httpservletrequest request) public void reset(actionmapping mapping,servletrequest request) 典型的actionfrom bean只有属性的设置与读取方法(getxxx),而没有实现事务逻辑的方法。只有简单的输入检查逻辑,使用的目的是为了存储用户在相关表单中输入的最新数据,以便可以将同一网页进行再生,同时提供一组错误信息,这样就可以让用户修改不正确的输入数据。而真正对数据有效性进行检查的是action类或适当的事务逻辑bean。 3、系统状态beans 系统的实际状态通常表示为一组一个或多个javabean类,其属性定义了当前的状态。 例如,在一个购物车系统中,将包括一个表示购物车的bean,这个bean为每个购物者所维护, 它包括了购物者所选择购买的物品条目。 另外,系统也包括保存用户信息(包括他们的信用卡和送货地址)、可获得的条目和当前库存水平这些不同的bean。 对于小规模系统,或是对于不需要长时间保存的状态信息,一组系统状态bean可以包含 所有系统曾经经历的特定细节的信息。 或者经常是,系统状态bean会表示永久保存在一些外部数据库中的信息(例如 customerbean 对象对应于customers表中特定的一行数据), 在需要时从服务器的内存中创建或清除。entity enterprise javabeans也是用于这种用途的。 4、商业逻辑beans 我们应该把
|
|