struts2原理



----------------------------------------struct2---------------------------------------------------

1 . 什么是struct2 ?
    面向程序员的java程序框架
    
    struts = jsp + servlet
    
    1.获得客户端参数
    2.数据类型转换
    3.数据格式验证
    4.将参数包装成一个pojo类型
    5.将需要显示的数据传递给jsp
    6.将请求放给jsp
    7.jsp显示servlet传递过来的数据
    
    
    
2. 为什么要学习struct2 ?
   提高代码复用,又快又好的提高web应用.
   
   快:  提供大量基础模块,加快web开发
   好:  应用了MVC 在内的好多的设计模式,提高代码的维护性
   
3. MVC 及struct的流程;
   基础模块的使用;
   
   1.表单验证;
   2.文件上传(文件拷贝);
   3.国际化(不同的语言版本);

4. 什么是MVC?
  
  定义: web应用开发框架
  
 组成:
   1.控制器(Controller)
     1.接收客户端请求
     2.根据请求调用相应的模型层方法
     3.选择一个视图层进行响应
   2.模型层(Model)
     1.封装应用的状态信息
     2.提供方法处理状态信息的方法
     3.重新将状态信息显示到视图层
   3.视图层(view)
     1.用户根系统交互的接口
     2.发送请求给控制器
     3.接收模型层的通知重新显示数据  
   
 流程:(web应用里的MVC)
       view<---->Controller<----->Model<---->持久层<---->DB
       
       M :javaBean(封装数据,封装数据访问逻辑)   sessionBean 
       ---------------------------------------------------------
       V: html ,xml , jsp
       ---------------------------------------------------------
       C: servlet ,  struts1: actionForm,actions
                     struts2: FilterDispatcher Actions
       
       注意:
       dao 模式中的service , Dao ,action 层 主要属于 Model层
       jsp ,html 页面等属于 View层
       servlet ,或者struts中的 FilterDispatcher属于Controll层
  
 层:考虑软件的维护性              |
                                   |                 软件                               公司
                                   
   原始的两层结构:                 |                功能                               职责
     
      1. 交互层                    |                 层                                 部门
      
      2. 处理层                    |                表现层(view)  (jap,html)           市场部
                                   |                ( 1.接受请求
                                   |                  2.呈现结果)
                                   |                      
                                   |                 控制层(controller)  (servlet)     管理部
                                                       Mapping
                                                      (将请求发给合适的模型层)
                                                      (将响应发给相应的表现层)
                                   |                      
                                   |                 模型层(Model)     (javaBean)      生产部
                                   |                       处理请求,业务逻辑
                                   |                   
                                                     持久层(dao模式)            (jdbc,hibernate)
                                                       实现数据的crud                   仓管
                                   
                                   |                 数据库 (dao)                        仓库
                                   |





 5.MVC的种类:
  模式一; (jsp作为控制)
  模式二: (servlet作为控制)
  区别:控制实现的技术
  
 6. MVC模式2 中的servlet的数量:
  方式:(一般用第三种)
  1. 一个servlet
  2. 一个rvlet
  3. 一个总体流程控制的serv请求一个selet,多个具体流程控制的servlet

  7.MVC提供的功能:
    1.自动获得客户端提交的参数
    2.自动进行数据类型转换和数据格式验证
    3.自动进行数据的包装
    4.能够更方便的将显示的数据传递给视图
    5.自动进行请求的转发
    6.提供标签库,能够更方便的构建视图
    7.国际化的实现
    8.能够更方便的跟其他框架进行集成
  
  
  

 ------第二章-------- 
   1. 什么是struct ?
    最早的mvc开源框架
   
   DAO模式:(data access object) 数据访问对象
   分类:
      1. data access
               使用接口,降低持久层和持久调用层的耦合性
               Icustomer.java  持久调用层关注
               具体的接口实现完全有自己实现
      2.active domain object
              customer.java
   使用JavaBean封装和传递数据
     JavaBean的特点:
       1.属性
          作用:用来持有数据
       2.所有属性设置get,set方法
          好处:简化访问
       3.建议使用无参的构造器
          作用:简化实例化
       4.实现java.io.Serializable接口
          作用:序列化;

                           |------------------------Dao模式-------------------------------|
view<---->Controller<----->Model<--接口交互-->持久层(实现接口,实现不同的技术应用)<-接口交互--->DB

2.struct2对MVC各层的贡献:

   1. View
      struts框架标签
      
   2.Controller
      1.FilterDispatcher(总体流程控制)            ---变形前---->servlet
        类型:Filter
        作用:总体流程控制
        提供:有框架提供
        
      2. Action(子流程控制)                       ---变形前----->servlet
        类型:普通java类
        作用:具体流程控制
        提供:由程序员提供
        
      3.配置文件   struct.xml
         内容:那个请求,由哪个Action处理,跳转至那个页面显示
      
      4.拦截器:
         作用:提供基础模块,一个拦截器一个模块
       
   3.Model
     没贡献

3.struct2.的流程时序:
   1.用户发出请求;
       http://localhost:8080/struct2/login.action
       http://localhost:8080/struct2/register.action
       
       /struct2 :request.getContextPath();
       /struct2 :request.getServletPath();
       
   2.FilterDispatcher处理请求;
     读取struct.xml,判断请求对应的Action是否存在
     -----------------
     web.xml
     <filter-mapping>
      <filter-name></filter-name>
      <filter-pattern>*.action</filter-pattern>    
     <filter-mapping>
     
     / :代表服务器根路径:
       1.<form action="/a.action">
       2. response.sendRedirect("a.jsp");
     
   3.拦截器处理请求()
      提供基础功能:
         将请求参数传递给Action对象属性;
         文件上传;
   4.Action处理请求
     调用模型层处理请求
     register.jsp
             RegisterAction.java
             src/struts.xml           

      view<---->Controller<----->Model<---->持久层<---->DB

     
   5.相应结果资源执行
   
   6.拦截器处理结果
   
   7.浏览器显示结果

 -----------regist.jsp----------
     Customer Register
     -----------------
     name:[  ]
     password:[  ]
     address:
     tel:
     
     register  reset

-----------------------------
  

 xml文件:
    良构性
    有效性:DTD schema
-----------------tomcat 5.0 与struct2及jdk解析问题---------------------------------------------------
配置:
----------tomcat安装路径/common/endorsed/覆盖所有-------------------
 
----------------------------------------------------------

4.作用域:

request

session                          setAttribute(String s,Object o);
                                 Object getAttribute(String s,Object o);
Servletcontext

5.struts中个组件的功能:
   1.控制层:
     类别:
      1.ActionServlet(公司老总)
        由框架提供的一个类,接收客户端的所有请求,但是本身不会处理请求,
         而是将请求委托给requestProcessor全权处理
      2.requestProcessor(项目经理)
         struts提供的一个类,用来接收actionServlet 转发过来的请求
      3.Action:(程序员)
         框架提供的一个类,功能与Servlet一样作为控制器来控制和转发请求,
         并且由他开调用model 模块中相应的方法,完成相应的业务,并根据不同的结果
         选择不同的jsp视图显示
         注:我们程序员要做的就是要完成Action类
    2.model层:
       ActionForm:
         由struts提供的一个类,作用:
             1.封装提交表单中的字段信息
             2.对提交表单中的字段信息进行验证(服务端验证)
             3.可以对表单中的信息进行重新赋值
             
        注意:1.我们用户也要定义一个类去继承actionForm
              2.一个action可以配置一个actionForm,也可以不配置,
                actionForm可以被多个action使用
                
         
  6.struts的环境搭建:
     1.构建web工程导入struts jar包
     
     2.在web.xml中配置主控器:(FilterDispatch)
        <filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
     
     3.在src目录下创建struts.xml,(struts.property.log4j.property文件)
  
  7.使用struts的基本步骤:
      1.创建jsp月面.提供用户输入表单页面,注意下action属性的配置
      
      2.创建相应的action类.
         1.提供属性用来存放提交的信息,
         2.设置get/set方法,
         3.提供execute()方法;
        注意:property 的名字必须与客户端提交的参数名字相同
     
      3.在struts.xml中配置action,包括名字和类型,并提供action返回的字符串
        以让中控器来控制跳转页面,显示
                <action name="ct" class="web.action.ConverterAction">
<result name="success" >/co.jsp</result>
</action>
           注意:<result name="success" >中的name必须与程序action中execute()
              方法返回的字符串值相同;
           目的:为了让主控器根据返回值控制跳转
             
     

  ---第三章---Action  results----
  1. Action
    
    action类的实现方法:
       1.普通的java类,不去实现任何方法,或接口
       2.实现 action接口
              优点:可以使用action接口中定义的常量
       3.继承actionSupport类:
              优点:可以再自定义的类中使用actionSupport中
                   定义的方法;
  
    1.访问Servlet 中对象的方式:
      1.使用ActionContext 辅助类(优先推荐使用)
      2.实现接口:servletContextAware
                 servletRequestAware
                 servletResponseAware
      3.使用ServletActionContext
      
      
      //Action 访问servlet api 
   //方式一:(推荐方式)
ActionContext.getContext().getSession()                  //方法链条
                         .put("smsg", e.getMessage());
   //方式二:
request.setAttribute("rmsg", "request:"+e.getMessage());

           //方式三:
ServletActionContext.
                   getServletContext()
                   .setAttribute("amsg", "application:"+e.getMessage());
      
      选择依据:
          1. 对代码是否有侵入性
          2. 是否引入新的api ,是否便于测试

    2.action的配置:
    
      一个Action处理多个请求
      将多个请求代码写在一个Action的不同方法中
      
      如何区别请求以调用合适的方法:
        1. 提交请求时 通过 !方法名  形式制定调用方法
                <form action="registCustomer.action!regist" method="post">
        
                <action name="customer" class="web.action.CustomerAction">
<result name="registSuccess">/login.jsp</result>
<result name="regisErr">/register.jsp</result>
<result name="loginSuccess">/index.jsp</result>
<result name="loginErr">/login.jsp</result>
<result name="input">/register.jsp</result>
<interceptor-ref name="logger"/>
</action>
        
            web.action.CustomerAction.java
        2. 通过配置文件中的method属性指定调用的方法;
                <action name="loginCustomer" class="web.action.CustomerAction" method="login">
<result name="loginSuccess">/index.jsp</result>
<result name="loginErr">/login.jsp</result>
</action>
<action name="registCustomer" class="web.action.CustomerAction" method="regist">
<result name="registSuccess">/login.jsp</result>
<result name="regisErr">/register.jsp</result>
</action>
           
     3.通过通配符减少配置性新内容
        <action name="*Customer" class="web.action.CustomerAction" method="{1}">
<result name="registSuccess">/login.jsp</result>
<result name="regisErr">/register.jsp</result>
<result name="loginSuccess">/index.jsp</result>
<result name="loginErr">/login.jsp</result>
        </action>

     namespace :action 寻找action的路径,默认为 / ,配置为:
                <package name="jd0908" namesp="/a">

     4.解决转向的action不存在的处理方法:
       <default-action-ref name=""/>

2.results 响应资源的配置:
  1.  局部result:放在单个action之间的result为局部result
                <action name="registCustomer" class="web.action.CustomerAction" method="regist">
<result name="registSuccess">/login.jsp</result>
<result name="regisErr">/register.jsp</result>
</action>
    全局result:
        减少action中相同内容result的配置信息
                <global-resultas>
                <result name="registSuccess">/login.jsp</result>
                <global-resultas>
    使用的时候为就近原则
    
  2. 跳转方式:
    result type:
    设置跳转类型或响应资源类型
    1. redirect (客户端重定向)
     http://localhost:8899/struct2/register.jsp 
      <result name="registSuccess" type="redirect">/login.jsp</result>
      ----->
      http://localhost:8899/struct2/login.jsp
    2. dispatcher(默认)
    3.plainText
     
    4.Chain类型的result type:(服务器内部跳转)
        共享同一个请求方式,跳转至另一个action
        
        input.jap           chainA.jsp               chainB.jsp
        -------------  -->  ----------     -->      ---------------
        name=zs               name+=chainA;        name+=chainB;
        
        
        name=zs    ----->  zs->chainB
        name=      ----->  ->chainB
                   ----->  null->chainA->chainB
                   
        1.有共同的参数和属性,优先选择参数值
        
     
  3. 动态result:不知道跳转到何处,跳转位置由客户决定
         将action属性值作为result路径或部分组成内容
         
         获得属性值:${属性名}
         
     <action name="baidu" class="web.action.BaiduAction">
<result name="success">${path}</result>
     </action>
     
  --- 第四章---Struts tag Library-------------------  
    1. struts标签分类:
      1.non-UL (非用户界面标签)
      
           1. (流程控制标签)  
                <s:iterator id="" value="map/list/set/array" status=""/>
                 id:如果指定了Id,迭代出来的数据除了放在值栈中外,还放在ActionContext中
                 status:存放当前数值的状态信息
                 
                <s:if test=""/>
                   当test中的值为真时执行本体中的内容
           2. (date标签)  
                <s:property value=""/>
                    从值栈中取值
                <s:set name="" value="" scope=""/>
                   将value表示的值设置到为name的作用于中;
                <s:push value=""/>
                   将某个值放到值栈顶
                
         具体的见<<J2EE笔记>>
        
     2.ul(用户界面标签)
        form 表单和非表单标签:
        
                        <body>
        <center>
<h3><br></h3><h3>Customer Register</h3>
<s:form action="register" >
<s:textfield name="name" label="Name"/>
<s:password name="password" label="Password"/>
<s:checkboxlist name="hobby" label="Hobby"
   list="#{'计算机':'computer','play':'playing','read':'reading'}" 
   listKey="value" 
   listValue="key"  
   value="{'reading'}"/> <!-- 预先选定的值 -->
<s:radio name="gender" label="Gender" 
   list="#{'男':'male','女':'remale'}"
   listKey="value"
   listValue="key"
   value="'male'"/>
<s:datetimepicker name="date" label="birdDay"/>
<s:set name="date" value="#{
   '上海市':{'闸北区','黄浦区','嘉定区'},
   '山东省':{'潍坊市','济南市','枣庄市','威海市'},
   '内蒙古':{'呼和浩特','呼伦贝尔','包头'}
}"/>
<s:doubleselect label="地址" name="address"
     list="#date.keySet()" 
     doubleName="c" 
     doubleList="#date[top]"></s:doubleselect>  
<s:textarea label="other" name="text" cols="10" rows="3"/>
<tr><td colspan="2" align="center">
<s:submit value="submit" align="center" theme="simple"/>
<s:reset value="reset" align="center" theme="simple"/> 
</td></tr>
</s:form>
        
        
     3.AJAX
     
注意:
      在struts中如何将action交给jsp实现?
      
        1.将数据放在在request范围内传递过去,然后jsp在从request范围取出,显示
        2.将要传递的数据作为action的一个实例变量(action的引用会被struts框架 放置在值栈中) ,jsp再从值栈中获得
     
    2 .ognl(对象图导航语言) 
       标记库组成:
        1.标记库处理类
        2.标记库描述文件
        3.jsp中使用;
     <%@taglib uri="" prifix=""%>
     1.标记库描述路径;
     2.标记库描述文件在web.xml中取的别名(使用路径的改变)
     3.标记库描述文件中uri元素内容  (推荐使用)
  
   
       访问实例:
<h2>ognl的使用</h2>
<h3>ognl表示的具体值</h3>
字符串:
<s:property value="'hello world'"/><br>
数值:
<s:property value="100"/><br>
Boolean:
<s:property value="false"/><br>
运算:
1+1=
<s:property value="1+1"/><br>
1>2?
<s:property value="1>2"/><br>
'a'.equals('b')?
<s:property value="'a'.equals('b')"/><br>

<h3>定义数组</h3>
{#request.s1,'hellow',23}

<h3>定义map</h3>
{'s1':#request.s1,'name':'hellow'}

<h3>访问各种作用域的对象</h3>
page:<br>     #attr.属性名称(先从page中找.若没有则在request中找,没有在到其他的里面中依次)
request:<br>  #request.属性名称
session:<br>  #session.属性名称
application:<br>  #application.属性名称
action:<br>   #属性名称(attribute)
valueStatck:<br> 对象的属性名(property)
parameter: #parameters.属性名:   访问请求的参数

<h3>访问静态方法</h3>
<s:property value="@java.Math@random()"/>   //生成一个随机数

<h3>获得参数</h3>
<s:property value="#parameters.n1[0]"/>   //得到参数值形成的数组,再得到某个元素  
       
       访问actionContext中的数据:
         <S:property value="#key"/>
       
----------第四章--格式转换和------------------

  1. 内置类型转换器:
      1.转换成特定的类型转换对象
          1.jsp:
            <input name="cust.name"/>
            <input name="cust.password"/>
          2.action:
            private Customer cust;
          3.result jsp:
            <s:propertry value="cust.name"/>

      2.转化成数组:
          1.jsp:
            <input type="checkbox" name="hobby>
            <input type="checkbox" name="hobby>
          2.action:
            private String[] hobby;
      3.转化成List:
          1.jsp:
            <input type="checkbox" name="hobby>
            <input type="checkbox" name="hobby>
          2.action:
            private List<String> hobby;
      4.转化成map:
         1.jsp:
            <input type="text" name="h.a>
            <input type="text" name="h.b>
            <input type="text" name="h.c>
         2.action:
           private Map<String,Strin> h;
  2. 自定义的类型转换器:
       1.编写一个类(类型转换处理类)
          1.继承StrutsTypeConverter 类:
          2.重写方法:
              convertFromString();    拦截器去调用
              convertToString();       拦截器去调用

         例:
          zs:123:shanghai:123456-------->Customer
          String[] split(":");
     
      2.通过配置文件,告诉框架类型转换器的存在
             1.名称:
                ActionName-conversion.properties
                例:   ConverterAction-conversion.properties
             2.路径:
               和Action 同目录
             3.内容:
               属性名称=类型转换器完整类名称
               例: cust=web.converter.CustomerConverter


  3.interceptor(拦截器)
       1. 什么是拦截器?
          struts中的Filter
          
          1. 拦截器是struts框架中提供基础服务的一种组件,在Action运行前后执行
          2. 当多个Action使用同一种功能时,可以将这个功能放在拦截器中
          3.拦截器是可以重用的,当某个拦截器需要某种功能时,只要用拦截器去拦截这个Action
          
       2.问什么要使用拦截器?
          为了维护性,重用性
       3.拦截器栈:多个拦截器
       
  4.如果没有显示的让某个Action去使用某个拦截器,Action会使用框架提供的默认的拦截器
    如果显示的调用了某个拦截器,必须在显示调用默认的拦截器
  
  5. 拦截器的使用:
      1.先写一个拦截器处理类,实现Interceptor接口
          init(),destory() ,intercept();
          主要实现intercept();
      2.通过配置是用拦截器
          1.  <interceptors>
    <interceptor name=" 名字" class="完整类名"/>
    </interceptors>
    注意:必须放在配置文件的最前面,否则出错
          2.    <action name=" " class=" ">
<result name="success" >/bidroutput.jsp</result>
<interceptor-ref name="名字"/>
<interceptor-ref name="defaultStack"/>
</action>
              注意:要注意.要显示调用默认的拦截器,否则出错

   6.内置的拦截器:
      
      1.Params:
         实现将请求提交的参数传递给action,
         
      2.staticParams:
        将action配置的参数值传递给action同名属性
        <param name="className">jd0908</param> -----js0908-------> private String className;
      3.Autoiring  与spring框架配合使用(不是默认的defaultStack)
      4.FileUploads:
         文件上传
         注意:
         1.在请求的即将结束的时候服务器会将上传的临时文件删除,同时复制一份保存在服务器端
         2.客户端请求方式必须为post方式,
           <s:form action="upload" enctype="multipart/form-data">
<s:file name="pic" label="File"></s:file>
<s:submit value="submit"></s:submit>
          </s:form>
         3.服务器端:
           //制定好上传的临时文件
  private File  pic;
  //制定上传的文件名
  private String picFileName;
  
  private void fileCopy() {
BufferedInputStream in = null;
BufferedOutputStream out = null;

try {
String path = ServletActionContext.getServletContext().getRealPath("/upload");
        System.out.println(path);
in = new BufferedInputStream(new FileInputStream(pic));

out = new BufferedOutputStream(new FileOutputStream(path+"\\"+picFileName));
//判断文件是否读取完毕
int i = -1;
//用来存放读取到的字节内容
byte[] buffer = new byte[1024*8];
while((i=in.read(buffer))!=-1){
out.write(buffer,0,i);
}

} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(in!=null) in.close();
if(out!=null) out.close();
} catch (Exception e) {
}
}
           
      5. validation
           表单验证  
           
           
 --第四章---validation--表单验证--------------     
       
   1.什么是表单验证: 
      判断用户提交的参数是否正确:
         1.该填的是否填写
         2.格式是否正确
         3.长度是否正确        
    
   2.为什么验证:
      我们不能假设用户提交的数据是否都是正确的,避免服务器资源浪费或避免程序终止
      
   3.种类:
      1.客户端完成:  -------->javaScript
           尚未提交请求前,由浏览器先行完成
           
      2.服务器端完成 :  ------->java 
      
      流程: 客户端提交请求----->判断是否有错误------有---->inputaction
                                      |
                                      |---->没有---->其他执行
           
            1.手动验证:
                 1. 必须继承ActionSupport
                     实际开发中我们继承 FieldValidatorSupport 类
                 2. 重写validate()方法
                    或者validateXXXX()方法;(例如:validateLogin();)
                    
       public void validateRegist(){
String name = cust.getName();
String pwd = cust.getPassword();

if(name==null||name.trim().length()==0){
addFieldError("name", "please input your name!!!!");
}
if(pwd==null||pwd.trim().length()==0){
addFieldError("pwd", "please input your password!!!!");
}
}
            
                 3.提供input名称的result
                 <result name="input">/register.jsp</result>
                 当出错时,系统自动调用input对应的action
                 
                 4.使用标记显示错误信息
                     <s:fielderror/>          ------>addFieldError();
                     <s:actionerror/>         ------>addActionError();
                     
姓名:<input type="text" name="cust.name"/>
<s:fielderror>
<s:param>name</s:param>
</s:fielderror>
<br>
密码:<input type="password" name="cust.password"/>
<s:fielderror>
<s:param>name</s:param>
</s:fielderror>
<br>
                     
            2.使用验证框架:
                  1. 必须继承ActionSupport
                  2.提供配置文件,告诉框架
                     1.那个名称的属性
                     2.进行什么类型的验证
                     3.出错提示信息 
                  
                 3.提供input名称的result
                 4.使用标记显示错误信息
              
             注意:与手动的区别是第二步不同
                    手动:
                       为重写validate()方法
                        或者validateXXXX()方法;(例如:validateLogin();)
                    框架:
                        使用配置文件
                  
                当有多个验证,时为了节省资源不去验证下面的:
                   配置: short-circuit="true"
                   
                  <field-validator type="stringlength" short-circuit="true">
                      
          <1>  怎么使用;
             配置文件名称:
                    类名(action类名)-validation.xml
                   或: 类名(action类名)-aliasName-validation.xml
                   
                   注:
                      类名(action类名) 必须为:对应的那个action类名
                      别名aliasName 必须为提交过来的那个action的类名
                  
                  例:
                    registCust.action----->CustomerAction.java
                                             .regist()
                                             
                     CustomerAction-registCust-validation.xml
           
             路径:
                 与action同一目录
      
      配置文件:
           
      <validators>
  <field name="cust.name" >
  <field-validator type="requiredstring">
  <message>Please Input Your Name......</message>
  </field-validator>
  </field>
  <field name="cust.password" >
  <field-validator type="requiredstring">
  <message>Please Input Your Password......</message>
  </field-validator>
  </field>
      </validators>
        
     jsp配置:
          <form action="registCustomer.action" method="post">
姓名:<input type="text" name="cust.name"/>
<s:fielderror>
<s:param>cust.name</s:param>
</s:fielderror>
<br>

<2> type 内置表单验证处理类
          <field-validator type="requiredstring">  
          
  <validators>
    <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
    <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
    <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
    <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
    <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
    <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
    <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
    <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
    <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
    <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
    <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
    <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
    <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
  </validators>
          
          
         1.required:
             当空时提交为 ""
         2.requiredstring :
             注:与required的区别为:
                当空时提交为 null
             <field-validator type="requiredstring">
  <message>Please Input Your Name......</message>
      </field-validator>
         3.stringlength:
                <field-validator type="stringlength">
     <param name="minLength">6</param>
     <param name="minLength">6</param>
  <message>Please Input Your Name is 6 to 8 ......</message>
  </field-validator>
         4.int:
        
       <3> 自己定义表单验证处理类:
             1.实现接口 Validator或继承父类 FieldValidatorSupport
             2.通过配置文件告诉框架该类的存在
              位置:
                 classpath/validators.xml 即在src目录下
              
            使用自己的验证类:
             
            第一步:    创建类: 
             
    public class PrefixValidator extends FieldValidatorSupport{

       private  String prifix="021";

       public void validate(Object arg0) throws ValidationException {

String fieldName = getFieldName();
String fieldValue = (String) getFieldValue(fieldName, arg0);

if(!fieldValue.startsWith(prifix)){ 
    addFieldError(fieldName, "must start begin with "+prifix);
}

}
             第二步:  设置配置文件:
              
              <?xml version="1.0" encoding="UTF-8"?>

       <!DOCTYPE validators PUBLIC
  "-//OpenSymphony Group//XWork Validator Config 1.0//EN"
  "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
 
     <validators>
     <validator name="prefix" class="web.validator.PrefixValidator"/>
     </validators>  
     
   第三步:在使用的地方配置:(自定义的配置文件中 例:CustomerAction-registCust-validation.xml)

<field name="cust.password" >
     <field-validator type="prefix">
  <message>Please Input Your Password......</message>
     </field-validator>
         </field>
         
   
  ------第五章   国际化------- 
  
    1.
    
    2.准备资源文件:
         
        1.创建配置文件:
            在某个目录下创建配置文件:
               名为:
                  xxx.properties
                  xxx_字符编码.propertie
                  
                  例:
                    laug.properties
                    laug_ch_CN.properties
                    
         注意:xxx_字符编码.propertie   ,中字符编码必须问真实的不能为任意的编码名
              
                 
        2. struts.xml配置:
           <constant name="struts.custom.i18n.resources" value="common.laug"/>
            根据配置文件找到配置的语言文件
        3.jsp中:
          <s:password name="password" key="label.password"/>