`

深入Struts1.1(下)

阅读更多

在Struts 1.1中,除了DynaActionForm以外,还提供了表单输入自动验证的功能,在包org.apache.struts.validator中提供了许多有用的类,其中最常见的就是DynaValidatorForm类。

DynaValidatorForm类

DynaValidatorForm是DynaActionForm的子类,它能够提供动态ActionForm和自动表单输入验证的功能。和使用DynaActionForm类似,你必须首先在配置文件中进行配置:

<form-beans>
 <form-bean name="loginForm" type="org.apache.struts.validator.DynaValidatorForm"> 
  <form-property name="actionClass" type="java.lang.String"/>     
  <form-property name="username" type="java.lang.String"/> 
  <form-property name="password" type="java.lang.String"/>  
 </form-bean>
</form-beans>

同时要定义验证的插件:

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
 <set-property property="pathnames"  
 value="/WEB-INF/validator-rules.xml,  
 /WEB-INF/validation.xml"/>
  </plug-in>

其中的validator.xml和validator-rules.xml分别表示验证定义和验证规则的内容(可以合并在一起),比如针对上例中的DynaValidatorForm,我们有如下验证定义(validator.xml):

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE form-validation PUBLIC  
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0//EN"  
"http://jakarta.apache.org/commons/dtds/validator_1_0.dtd">
<!--    Validation Rules    $Id: validation.xml-->

<form-validation>  
<!-- ========== Default Language Form Definitions ===================== -->
<formset>  
 <form name="loginForm">     
  <field property="username" depends="required, minlength,maxlength"> 
   <arg0   key="prompt.username"/>          
   <arg1   key="${var:minlength}" name="minlength" resource="false"/>       
   <arg2   key="${var:maxlength}" name="maxlength" resource="false"/>              
   <var>                
    <var-name>maxlength</var-name>    
    <var-value>16</var-value>         
   </var>          
   <var>      
    <var-name>minlength</var-name>     
    <var-value>3</var-value>         
   </var>       
  </field>     
  <field property="password" depends="required, minlength,maxlength" bundle="alternate">          
   <arg0   key="prompt.password"/>   
   <arg1   key="${var:minlength}" name="minlength" resource="false"/>          
   <arg2   key="${var:maxlength}" name="maxlength" resource="false"/>  
   <var>              
    <var-name>maxlength</var-name>     
    <var-value>16</var-value>        
   </var>          
   <var>      
    <var-name>minlength</var-name> 
    <var-value>3</var-value>       
   </var>        
  </field>    
 </form>   
</formset>
</form-validation>

从上述定义中,我们可以看到对于字段username有三项验证:required, minlength, maxlength,意思是该字段不能为空,而且长度在3和16之间。而validator-rules.xml文件则可以采用Struts提供的缺省文件。注意在<form-bean>中定义的form是如何与validation.xml中的form关联起来的。最后,要启动自动验证功能,还需要将Action配置的validate属性设置为true。

<action path="/login"  
type="com.ncu.test.LoginAction"
name="loginForm"          
scope="request"         
input="tile.userLogin"validate="true">

此时,Struts将根据xml配置文件中的定义来检验表单输入,并将不符合要求的错误信息输出到页面。但是你可能会想:这个功能虽然好,可是什么检验都跑到服务器端执行,效率方面和用户易用性方面是不是有些问题?你可能会怀念起那简单的JavaScript客户端验证。

不用担心,在Struts 1.1中也支持JavaScript客户端验证。如果你选择了客户端验证,当某个表单被提交以后,Struts 1.1启动客户端验证,如果浏览器不支持JavaScript验证,则服务器端验证被启动,这种双重验证机制能够最大限度地满足各种开发者的需要。JavaScript验证代码也是在validator-rules.xml文件中定义的。要启动客户端验证,你必须在相应的JSP文件中做如下设置:

  1. 为<html:form>增加onsubmit属性
  2. 设置Javascript支持

 

下表中列出了一JSP文件的示例代码,红字部分为Javascript验证所需代码。

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<table bgcolor="#9AFF9A" cellspacing="0" cellpadding="10" border="1" width="100%">
 <tr>
 <td> 
 <table cellspacing="0" cellpadding="0" border="0" width="100%"> 
 <tr bgcolor="#696969"> 
  <td align="center">     
  <font color="#FFFFFF">Panel 3: Profile</font>  
  </td>
  </tr> 
 <tr>  
  <td><br> 
  <html:errors/>  
  <html:form action="/login.do" focus="username"  onsubmit="return validateLoginForm(this);">  
  <html:hidden property="actionClass"/>   
  <center>      
  <table>      
   <tr>        
   <td>UserName:</td>   
   <td><html:text property="username" size="20"/></td> 
   </tr> 
   <tr>  
   <td>Password:</td>   
   <td><html:password property="password" size="20"/></td>    
   </tr>  
   <tr>  
   <td colspan=2><html:submit property="submitProperty" value="Submit"/></td>     
  </table>   
  </center>  
  </html:form> 
  <html:javascript formName="loginForm" dynamicJavascript="true" staticJavascript="false"/>  
 
 <script language="Javascript1.1" src="staticJavascript.jsp"></script>  
 </td> 
 </tr> 
 </table>
 </td>
 </tr>
</table>

其中onsubmit的值为"return validateLoginForm(this);",它的语法为:

return validate + struts-config.xml中定义的form-bean名称 + (this);

staticJavascript.jsp的内容为:

<%@ page language="java" %>
<%-- set document type to Javascript (addresses a bug in Netscape according to a web resource --%>
<%@ page contentType="application/x-javascript" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:javascript dynamicJavascript="false" staticJavascript="true"/>

如果validator-rules.xml中定义的基本验证功能不能满足你的需求,你可以自己添加所需的验证类型。

Action

我们通过继承Action类来实现具体的执行类。具体Action类的功能一般都在execute(以前是perform方法)方法中完成,其中主要涉及到以下几个方面:

  1. 辅助ActionForm进行一些表单数据的检查。
  2. 执行必要的业务逻辑,比如存取数据库,调用实体bean等。
  3. 更新服务器端的bean数据,后续对象中可能会用到这些数据,比如在JSP中利用bean:write来获得这些数据。
  4. 根据处理结果决定程序的去处,并以ActionForward对象的形式返回给ActionServlet。

 

提示:由于在Action和ActionForm中都可以实现验证方法,那么如何来安排它们之间的分工呢?一般来说,我们秉着MVC分离的原则,也就是视图级的验证工作放在ActionForm来完成,比如输入不能为空,email格式是否正确,利用ValidatorForm可以很轻松地完成这些工作。而与具体业务相关的验证则放入Action中,这样就可以获得最大ActionForm重用性的可能。

前面我们提到过,我们主张将业务逻辑执行分离到单独的JavaBean中,而Action只负责错误处理和流程控制。而且考虑到重用性的原因,在执行业务逻辑的JavaBean中不要引用任何与Web应用相关的对象,比如HttpServletRequest,HttpServletResponse等对象,而应该将其转化为普通的Java对象。关于这一点,可以参考Petstore中WAF框架的实现思路。

此外,你可能还注意到execute与perform的一个区别:execute方法简单地掷出Exception异常,而perform方法则掷出ServletException和IOException异常。这不是说Struts 1.1在异常处理功能方面弱化了,而是为了配合Struts 1.1中一个很好的功能--宣称式异常处理机制。

宣称式异常处理

和EJB中的宣称式事务处理概念类似,宣称式异常处理其实就是可配置的异常处理,你可以在配置文件中指定由谁来处理Action类中掷出的某种异常。你可以按照以下步骤来完成该功能:

  1. 实现org.apache.struts.action.ExceptionHandler的子类,覆盖execute方法,在该方法中处理异常并且返回一个ActionForward对象
  2. 在配置文件中配置异常处理对象,你可以配置一个全局的处理类或者单独为每个Action配置处理类

 

下表就定义了一个全局的处理类CustomizedExceptionHandler,它被用来处理所有的异常。

<global-exceptions> 
<exception 
 handler="com.yourcorp.CustomizedExceptionHandler" 
 key="global.error.message" 
 path="/error.jsp"    
 scope="request"    
 type="java.lang.Exception"/>
</global-exceptions>

其中具体的参数含义,可以参考ExceptionHandler.java源文件。

taglib

讲完了模型和控制器,接下来我们要涉及的是视图。视图的角色主要是由JSP来完成,从JSP的规范中可以看出,在视图层可以"折腾"的技术不是很多,主要的就是自定义标记库的应用。Struts 1.1在原有的四个标记库的基础上新增了两个标记库--Tiles和Nested。

其中Tiles除了替代Template的基本模板功能外,还增加了布局定义、虚拟页面定义和动态页面生成等功能。Tiles强大的模板功能能够使页面获得最大的重用性和灵活性,此外可以结合Tiles配置文件中的页面定义和Action的转发逻辑,即你可以将一个Action转发到一个在Tiles配置文件中定义的虚拟页面,从而减少页面的数量。比如,下表中的Action定义了一个转发路径,它的终点是tile.userMain,而后者是你在Tiles配置文件中定义的一个页面。


<!-- ========== Action Mapping Definitions ============================== -->
<action-mappings>  
<!-- Action mapping for profile form --> 
 <action path="/login"   
  type="com.ncu.test.LoginAction"      
  name="loginForm"    
  scope="request"     
  input="tile.userLogin"
  validate="true">     
  <forward name="success" path="tile.userMain"/>   
 </action> 
</action-mappings>

Tiles配置文件:tiles-defs.xml


<!DOCTYPE tiles-definitions PUBLIC 
"-//Apache Software Foundation//DTD Tiles Configuration//EN"       "http://jakarta.apache.org/struts/dtds/tiles-config.dtd">
<tiles-definitions>  
<!-- =======================================================  --> 
<!-- Master definitions                                       -->
<!-- =======================================================  --> 
<!-- Page layout used as root for all pages. --> 

<definition name="rootLayout" path="/tiles-layouts/rootLayout.jsp"> 
 <put name="titleString" value="CHANGE-ME"/>   
 <put name="topMenu" value="/tiles-components/topMenu.jsp"/> 
 <put name="leftMenu" value="/tiles-components/panel1.jsp"/>  
 <put name="body" value="CHANGE-ME"/>   
 <put name="footer" value="/tiles-components/footer.jsp"/> 
</definition> 

<!-- =======================================================  --> 
<!-- Page definitions      -->  
<!-- =======================================================  --> 

<!-- User Login page --> 
<definition name="tile.userLogin" extends="rootLayout"> 
 <put name="titleString" value="User Login"/>  
 <put name="body" value="/src/userLogin.jsp"/> 
</definition>  
<!-- User Main page --> 
<definition name="tile.userMain" extends="rootLayout"> 
 <put name="titleString" value="User Main"/>  
 <put name="body" value="/src/userMain.jsp"/> 
</definition>
</tiles-definitions>

而Nested标记库的作用是让以上这些基本标记库能够嵌套使用,发挥更大的作用。

Commons Logging 接口

所谓的Commons Logging接口,是指将日志功能的使用与日志具体实现分开,通过配置文件来指定具体使用的日志实现。这样你就可以在Struts 1.1中通过统一的接口来使用日志功能,而不去管具体是利用的哪种日志实现,有点于类似JDBC的功能。Struts 1.1中支持的日志实现包括:Log4J,JDK Logging API, LogKit,NoOpLog和SimpleLog。

你可以按照如下的方式来使用Commons Logging接口(可以参照Struts源文中的许多类实现):


package com.foo;
// ...
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//...
 public class Foo {    
 // ...    
 private static Log log = LogFactory.getLog(Foo.class);
 // ...    
 public void setBar(Bar bar) {       
  if (log.isTraceEnabled()) {         
   log.trace("Setting bar to " + bar);   
  }      
 this.bar = bar;   
 }
// ...
}

而开启日志功能最简单的办法就是在WEB-INF/classes目录下添加以下两个文件:

commons-logging.properties文件:


# Note: The Tiles framework now uses the commons-logging package to output different information or debug statements. 
Please refer to this package documentation to enable it. The simplest way to enable logging is to create two files in 
WEB-INF/classes:
# commons-logging.properties
# org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
# simplelog.properties
# # Logging detail level,
# # Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
#org.apache.commons.logging.simplelog.defaultlog=trace
org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog

simplelog.properties文件:


# Logging detail level,
# Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
org.apache.commons.logging.simplelog.defaultlog=fatal

这里我们采用的日志实现是SimpleLog,你可以在simplelog.properties文件指定日志明细的级别:trace,debug,info,warn,error和fatal,从trace到fatal错误级别越来越高,同时输出的日志信息也越来越少。而这些级别是和org.apache.commons.logging.log接口中的方法一一对应的。这些级别是向后包含的,也就是前面的级别包含后面级别的信息。

分享到:
评论

相关推荐

    struts1.1源代码

    在深入理解 Struts 1.1 源代码之前,我们需要对 MVC 设计模式有所了解。 1. MVC 设计模式: MVC 将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。模型负责处理业务逻辑,视图...

    深入Struts 1.1

    论Struts 1.1框架的关键特性及其...通过深入理解Struts 1.1的组件和工作原理,开发者可以更好地构建可扩展、可维护的大型企业级应用。在实际开发中,正确地使用Struts 1.1的各种特性,能够显著提升开发效率和应用质量。

    Struts 1.1 API.zip

    7. **国际化和本地化**:Struts 1.1支持国际化的消息资源管理,通过`messageResources`配置项,可以在不同语言环境下显示相应的文本。 8. **异常处理**:Struts 1.1提供了ActionError和ActionMessages机制,用于...

    struts1.1_EJB小例子

    这个"struts1.1_EJB小例子"很可能是演示如何在Struts 1.1框架下集成和使用EJB。具体实现可能包括创建一个Action,该Action通过调用EJB来处理业务逻辑,然后返回结果给客户端。通过分析源码,我们可以学习到如何在Web...

    struts1.1+ejb模拟项目

    Struts1.1是Apache软件基金会下的一个开源MVC(Model-View-Controller)框架,主要用于构建基于Java的Web应用程序。它提供了结构化的控制层,使得开发者能够更好地分离业务逻辑、数据模型和用户界面,从而提高代码的...

    Struts 1.1 API 英文版

    通过阅读Struts 1.1 API的英文版,开发者能够深入理解框架的工作原理,有效地利用其功能,提高开发效率。尽管现在Struts已经发展到2.x版本,但1.1版的API对于学习MVC框架的基本思想和历史背景仍然具有很高的参考价值...

    struts1.1 api

    在本文中,我们将深入探讨Struts 1.1 API的主要组件、功能以及如何利用它们来构建高效的Web应用程序。 首先,Struts的核心组件包括Action、ActionForm、ActionServlet和配置文件。Action是处理用户请求的业务逻辑...

    jakarta-struts-1.1.zip_jakarta-Struts-1_jakarta-struts 1_jakarta

    Jakarta Struts 1.1 是一个历史悠久的Java ...通过查阅其中的API文档,开发者可以深入理解如何使用Struts来构建高效、可维护的Web应用。同时,这个压缩包也提醒我们技术的快速发展,以及不断学习和适应新技术的重要性。

    struts1.1api

    "重要说明.txt"可能包含了使用Struts 1.1 API时需要注意的事项和最佳实践,而"阅读器及更多E书下载.url"则可能是指向其他相关开发资源的链接,帮助开发者深入学习和理解Struts框架。 了解和掌握这些核心概念,...

    Commons Validator 1.3与Struts 1.1混合使用时的问题处理

    解决这些问题通常需要对Struts和Validator的工作原理有深入理解,以及熟悉XML配置和异常处理。通过仔细阅读官方文档,查阅相关论坛和博客,如给出的链接,可以找到更多解决问题的线索和示例代码。 在实际操作中,...

    ssh helps Struts1.1.chm Hibernate.chm Spring.chm

    Struts1.1版本在当时是非常流行的一个版本,它帮助开发者更好地组织和控制应用程序的流程,使得业务逻辑与展示层分离,提高代码的可维护性和可重用性。这个CHM文件可能会涵盖Struts的核心概念,如ActionForm、Action...

    深入Struts1.1

    本文就将带你走进Struts1.1去深入地了解这些功能。说明:希望本文的读者能有一定的Struts使用基础。Model2Struts是基于Model2之上的,而Model2是经典的MVC(模型-视图-控制器)模型的Web应用变体,这个改变主要是...

    精通Struts1.1

    《精通Struts1.1》是一本专注于Java Web开发领域中的经典著作,主要围绕着Struts 1.1框架展开,旨在帮助读者深入理解和熟练应用这个基于Model-View-Controller(MVC)设计模式的开源框架。Struts是Apache软件基金会...

    Repo1:Struts1.1 检查目的存储库

    在深入探讨Struts1.1的知识点之前,我们先来了解一下Struts的基本概念。 Struts是一个MVC(Model-View-Controller)框架,它提供了一种结构化的开发方式,将业务逻辑、数据模型和用户界面分离,使代码更易于维护和...

    struts2.3.1.1

    这个版本包含了文档、源码以及相关的库文件,对于开发者来说,是深入理解和自定义Struts2功能的重要资源。 首先,Struts2是一个流行的开源框架,由Apache软件基金会维护。它的核心功能是处理HTTP请求,提供强大的...

    Struts2.2.1.1源码

    Struts2.2.1.1源码是一个重要的开源框架,它是Apache软件基金会下的一个项目,主要用于构建基于Java的企业级Web应用程序。这个源码版本包含了Struts2框架的核心功能和其他相关组件,为开发者提供了深入理解其工作...

    struts1源代码

    深入学习Struts1的源代码,可以让我们更好地理解MVC模式在实际应用中的实现,了解控制层、模型层和视图层如何协作。同时,也能帮助我们了解Web应用程序的生命周期,以及如何通过配置文件来定制框架的行为。这对于...

    struts1_1api

    通过深入学习和理解Struts 1.1 API,开发者能够有效地构建和管理复杂的Web应用程序,提高开发效率,同时利用框架提供的功能来增强应用的可扩展性和可维护性。查阅CHM文档,可以帮助开发者快速定位并了解每个类、接口...

Global site tag (gtag.js) - Google Analytics