struts_05 各种验证器,ognl表达式,struts2常用标签,防止表单重复提交,jfreeChart插件的运用

一、用户输入验证
      1、编程方式:
            动作类中的所有方法进行验证:               
                  步骤:
                      a、动作类继承ActionSupport
                      b、覆盖调用public void validate()方法
                      c、在validate方法中,编写不符合要求的代码判断,并调用父类的addFieldError(String fieldName,String errorMessage)
                        如果fieldError(存放错误信息的Map)有任何的元素,就是验证不通过,动作方法不会执行。
                        Struts2框架会返回到name=input的result
                      d、在name=input指定的页面上使用struts2的标签显示错误信息。<s:fielderror/>
                      
                      
                  例子:
                   ********************************************************************************************************************
                   Action类:
                        public class UserAction extends ActionSupport implements Serializable {


                              private String username; // 用户名不能为空,其去掉首位空格
                              private String password; // 3~6为数字
                              
                              // set/get属性
                              
                              public String add(){
                                  System.out.println("执行了user的add方法");
                                  return SUCCESS;
                              }
                                                                
                              // 验证方法: 只考虑不符合条件的   注: 要继承com.opensymphony.xwork2.ActionSupport类
                              @Override
                              public void validate() {
                                  if(username==null||"".equals(username)){
                                      addFieldError("username", "用户名不能为空");
                                  }
                                  if(password==null||!password.matches("\\d{3,6}")){
                                      addFieldError("password", "密码长度必须是3~6位数字");
                                  }
                              }
                          
                        }
                        
                   jsp:
                        <body>    
                            <!-- 注:<s:fielderror fieldName="username"></s:fielderror> 要引入 uri="/struts-tags"包    用于动作类中数据校验的错误信息提示  -->
                            <!-- 访问地址:http://localhost:8080/struts2day02/validate/addUser.jsp    -->
                            <form action="${pageContext.request.contextPath}/validate/user_add.action" method="post">
                                  用户名:<input type="text" name="username"/> &nbsp;&nbsp; <s:fielderror fieldName="username"></s:fielderror>  <br/><br/>
                                  密码:   <input type="text" name="password"/> &nbsp;&nbsp; <s:fielderror fieldName="password"></s:fielderror>  <br/><br/>
                                  <input type="submit" name="保存" />
                            </form>                                                 
                        </body>
                   
                   ********************************************************************************************************************
            
            动作类中指定的方法进行验证:
                    编写步骤与上面相同
              
                    Action类中的验证方法书写有要求:
                        public void validateXxx()   Xxx代表的是要验证的动作方法名,其中要把动作方法名的首字母变为大写。
                        
                        
            输入校验的流程图
                  
        


      2、基于XML配置文件的方式:
              动作类中的所有方法进行验证:
                    在动作类的包中,建立一个名称为:动作简单类名-validation.xml ,  
                    比如要验证的动作类名是UserAction,则UserAction-validation.xml内容如下:
                    ********************************************************************************************************************
                        <?xml version="1.0" encoding="UTF-8"?>
                        <!DOCTYPE validators PUBLIC
                            "-//OpenSymphony Group//XWork Validator 1.0.3//EN"
                            "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
                            
                        <validators>
                        
                          <!--  写法1 根据字段提供不同的验证器 -->
                          <field name="username">
                              <!-- 内置验证器都是定义好的,在xwork-core.jar com.opensymphony.xwork2.validator.validators包中的default.xml文件中 -->
                              <field-validator type="requiredstring"> <!-- 不能为null或者""字符串,默认会去掉前后的空格 -->
                                  <param name="trim">true</param>
                                  <message>用户名不能为空</message>
                              </field-validator>
                          </field>
                          
                          <field name="password">
                              <field-validator type="requiredstring"> 
                                  <message>密码不能为空</message>
                              </field-validator>
                              <field-validator type="regex"> 
                                  <param name="expression"><![CDATA[\d{3,6}]]></param>  // 该参数由对应的内置验证器的类找,为了防止有特殊字符,转换成普通文本
                                  <message>密码长度必须是3~6位数字</message>
                              </field-validator>
                          </field>
                          
                          
                          <!-- 写法2 根据验证器,提供不同的字段   注: 此种方式需使用 <s:actionerror/>标签来显示错误信息   -->
                          <validator type="requiredstring">
                              <param name="fieldName">username</param>
                              <message>用户名不能为空</message>
                          </validator>
                          
                        </validators>
                      ********************************************************************************************************************
              
              动作类中指定的方法进行验证:
                    配置文件的名称书写有一定要求:  
                        动作类名-动作名(配置文件中的动作名)-validation.xml
                        如: UserAction-user_add-validation.xml
                        
                        
              struts2内置的各种验证器:
                  见struts2的参考讲义详解
                    
              
      3、自定义基于XML的验证器
              a、编写一个类,继承FieldValidatorSupport类或validatorSupport类。
              b、在public void validate(Object object)编写你的验证逻辑
                  不符合要求的就向fieldErrors中放消息
              c、一定注册你的验证器才能使用
                  在WEB-INF/classes目录下建立一个名称为validators.xml的配置文件,内容如下:
                  
                    <?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="strongpassword" class="cn.itcast.validators.StrongPasswordValidator"/>
                    </validators>
              d、日后就可以像使用Struts2提供的16个验证器方式去使用了。 





二、Struts2对于i18n的支持
       
        全局资源文件/包范围资源文件/动作类的资源文件
        全局资源文件:放到WEB-INF/classes目录下
        包范围资源文件:服务于Java类中的包下的动作类的。
            取名:package_语言_国家.properties
        
        动作类的资源文件:放到与动作类相同的包中
            取名:动作类名_语言_国家.properties
            
            
        jsp中如何读取国际化的消息
        动作类中如何读取国际化的消息
        
        
        
        
三、OGNL表达式:


      1. OGNL简介
            OGNL是从ActionContext中获取数据的。使用OGNL表达式需结合struts的<s:property value="OGNL表达式"/>使用
            struts2中的OGNL Context实现者为ActionContext,当struts接收一个请求时,会迅速创建ActionContext,ValueStack,action
                然后把action放进ValueStack中,所以action的实例变量可以被OGNL访问。
      
      2. ActionContext详解
            ActionContext的结构:
                ValueStack:    List结构:动作类放在此处。               
                application:   ServletContext中的那个Map
                session:       HttpSession中的那个Map
                request:       ServletRequest中的那个Map
                parameters:    请求参数的那个Map。(如同EL表达式的paramValues内置对象)
                attr:          相当于PageContext的findAttribute方法。在四大域范围内依次查找。
              
           注:
              valueStack:      取存放在ValueStack中的root的对象的属性,直接写即可,访问其他内容中的对象要使用#+(范围)
                               访问值栈对象中的属性时,可以直接根据属性名获取。如果栈顶元素没有该属性,则由第二个元素依次查找获取,
                               如果有多个相同名称的键,也可以由角标来确定
                               也可以直接通过EL表达式直接访问valueStack中对象的属性,struts2对HttpServletRequest进行了封装
                               先在request中找,如果找不到,则从栈顶元素找
                               如: ${username}就是获得值栈中某个对象的属性
              
              application对象: 用于访问ServletContext,例如#application.username或者#application['username'],
                               相当于调用ServletContext的getAttribute("username");
               
              session对象:     用来访问HttpSession,例如#session.username或者#session['username'],
                               相当于调用session.getAttribute("username");
              
              request对象:     用来访问HttpServletRequest属性(attribute)的Map,例如#request.username或#request['username']
                               相当于调用request.getAttribute("username");
                               
              parameters对象:  用于访问Http的请求参数,例如#parameters.username或者#parameters['username']
                               相当于调用request.getParameter("username");
                               
              attr对象:        相当于PageContext的findAttribute方法。在四大域范围内依次查找。
                               page-->request-->session-->application的顺序;
              
              
           小技巧:在页面中使用<s:debug/>查看上下文中的对象
                  s:debug标签用来显示对象是放在哪个域中,进而可以由此判断出ongl表达式要如何书写 
           
           
           例:
                ***********************************************************************************
                Action类:
                    public class PersonAction extends ActionSupport implements Serializable {
                          private String username;
                          private int age;                    
                          // set/get属性
                                              
                          public String execute(){
                            // 默认是放到值栈对象中的,可以直接根据属性名获取
                            username = "zql";   
                            age = 18;
                            
                            // 放到request中
                            ActionContext.getContext().put("user", "请求范围");
                            
                            // 放到session中,须要用#session.键来获取
                            ActionContext.getContext().getSession().put("user", "sesion范围");
                            
                            return SUCCESS;
                          }               
                      
                    }
                JSP:
                    <body>
                        <!-- 使用OGNL表达式 -->
                        <s:property value="username"/>        <br/>
                        <s:property value="[0].username"/>    <br/>
                        <s:property value="#request.user"/>    <br/>
                        <s:property value="#session.user"/>   <br/>
                        <s:property value="#attr.user"/>    <br/>
                        
                        <!-- 默认取valueStack中的栈顶对象  -->
                        <s:property/>                         <br/>
                        
                       <!-- EL表达式实现相同的获取 -->
                       <!-- 注: 此处是ognl表达式对值栈对象中的属性获取的封装,如果没有,则调用findAttribute方法 -->                
                        ${username}           <br/>
                        ${sessionScope.user}  <br/>
                        ${user}               <br/>               
                    </body>
                         
                ***********************************************************************************
     
     3. 利用OGNL表达式创建List/Map集合
            
           创建List集合
                ***********************************************************************************
                
                <!-- 创建list集合  默认放到了ActionContext上下文件中 scope="action" -->
                <s:set var="list1" value="{'a','b','c'}"></s:set> <br/>  
                <s:set var="list2" value="{'aa','bb','cc'}" scope="action" /> <br/>
                <s:set var="list3" value="{'aaa','bbb','ccc'}" scope="session"></s:set> <br/>
                    
                <!-- 获取list集合中的元素 -->  
                <s:property value="#list1[1]"/>  <br/>
                <s:property value="#list2[1]"/> <br/> 
                <s:property value="#session.list3[1]"/> <br/> <br/> 
                
                <!-- 遍历list集合中的元素 -->
                <s:iterator value="#session.list3" var="ls">
                  <s:property value="#ls"/> <br/>
                </s:iterator>
                
                
                <s:set var="list" value="{'a','b','c'}"></s:set>
                <s:iterator value="#list"> <!-- 注: 遍历时,会将当前遍历的对象放到valueStack的栈顶  l="a"-->
                  <s:property/> <br/>
                </s:iterator>
                  
                ***********************************************************************************  
     
           创建Map集合
                ***********************************************************************************
                
                <!-- 创建map集合 -->
                <s:set var="map1" value="#{'a':'valuea','b':'valueb'}" scope="session" />


                <!-- 获取map集合中的某个元素的值  ????? 取不出来 待百度 -->
                


                <!-- 利用jstl标签来遍历session域中的map1集合 -->
                <c:forEach items="${sessionScope.map1}" var="me">
                    ${me.key} = ${me.value} <br/>
                </c:forEach>
                
                <!-- 遍历map集合中的元素  对比jstl标签-->
                <s:iterator value="#session.map1" var="me">
                    <s:property value="#me.key"/> = <s:property value="#me.value"/> <br/>
                </s:iterator>
                
                
                <s:set var="map" value="#{'a':'aa','b':'bb','c':'cc'}"></s:set>
                <s:iterator value="#map"> <!-- 注: 遍历时,会将当前遍历的对象放到valueStack的栈顶  me=map.Entry-->
                    <s:property value="key"/> : <s:property value="value"/> <br/>
                </s:iterator>
                
                ***********************************************************************************
     
      4. in表达式:       <s:if test="'c' in {'a','b'}">
                          yes
                        </s:if>
                        <s:else>
                          no
                        </s:else>
                            
         not in表达式: 
                        <s:if test="'c' not in {'a','b'}">
                          yes
                        </s:if>
                        <s:else>
                          no
                        </s:else>
                      
                      
      5. ognl表达式的投影功能
            允许使用某个规则获得符合集合对象的子集,常用的有以下3个相关的操作符:
                ?:  获得所有符合逻辑的元素
                ^:  获得符合逻辑的第一个元素
                $:  获得符合逻辑的最后一个元素
                
            例:
                <!-- ognl表达式的投影功能   #this为当前遍历的对象  ?筛选符合条件的对象 -->
                <s:iterator value="books.{?#this.price>20}" var="book">
                  <s:property value="#book.name" /> &nbsp;&nbsp; <s:property value="#book.price"/> <br/>              
                </s:iterator>
            
            


四、Struts2中常用的标签
      
      1. 常用标签
              <s:property/>标签:用于输出指定值   
                      
                                ognl表达式动作类中的字段的值 
                                      <s:property value="username" />  
                                默认取valueStack中的栈顶对象      
                                      <s:property/> <br/>
      
      
      
                <s:set/>标签:   用于将某个值放入指定范围。
                                scope: 指定变量被放置的范围,该属性可以接受application,session,request,page,或action,
                                        如果没有设置该属性,则默认放置在OGNL Context中;
                                value:  赋给变量的值,如果没有设置该属性,则将ValueStack栈顶的值赋给该变量;
                         
              
              
              
                <s:if/else/>:   
                                <s:set var="grade" value="'C'"></s:set>   <!-- 如果把一个字符串当成了表达式,再用引号引起来就是字符串了 -->
                                <s:if test="#grade=='A'">
                                  优秀
                                </s:if>
                                <s:elseif test="#grade=='B'">
                                  良好
                                </s:elseif>
                                <s:else>
                                  及格
                                </s:else>
                
                
                
                </s:iterator>:  用于对集合进行迭代,包含list,set,和数组
                                当前迭代的元素在栈顶
                                <s:set var="records" value="{'辟邪剑法','玉女心经','葵花宝典','金瓶梅','艺术概论','小试牛刀','开发宝典'}" ></s:set>
                                <table border="1">
                                      <tr>
                                          <th>序号</th>
                                          <th>书名</th>
                                      </tr>
                                      <s:iterator value="#records" status="vs">
                                          <tr bgcolor="<s:property value='#vs.even?"red":"yellow"'/>">
                                              <td>
                                                  <s:property value="#vs.count"/>
                                              </td>
                                              <td>
                                                  <s:property />
                                              </td>
                                          </tr>
                                      </s:iterator>
                                </table>                  
              
              
              
                <s:url/>:       生成路径
                                <!-- 输出: /struts2day03/validate2/user_add.action  -->
                                <s:url action="user_add" namespace="/validate2"></s:url>     
                                                               
                                <s:url action="a12" var="url"> <!-- 还对URL进行了重写 -->
                                  <s:param name="username" value="'admin'"></s:param>    <!-- value的取值被当作表达式了,需要加引号才能转换为字符串 -->
                                  <s:param name="age" value="'28'"></s:param>
                                </s:url>
                                <a href="<s:property value="#url"/>">猛点</a> <br/>
                                                               
                                <s:set value="'addCustomer'" var="addr"></s:set>    <!-- 存放的动作名称 -->
                                <s:url value="%{#addr}"></s:url>                      <!-- url标签中value的取值: 默认是当作字符串的 若想要当作是表达式,须使用%{} -->
                                
                <s:a action=""/>  
            
                
                表单的标签:
                
                                Action类:
                                      public class StudentAction extends ActionSupport implements Serializable {
                                        private String[] hobby1 = {"吃饭","睡觉","打豆豆"};   // 选项
                                        private String[] hobby2;   //  被选中的选项                                  
                                        // set/get属性
                                        
                                        public String execute(){
                                            hobby2 = new String[]{"打豆豆"};
                                            return SUCCESS;
                                        }                                                                                                     
                                      }
                                      
                                JSP:
                                      <body>
   
                                            <s:checkboxlist name="hobby" list="{'吃饭','睡觉','打豆豆'}" value="{'吃饭','打豆豆'}"></s:checkboxlist>    <br>                 
                                            
                                            <s:checkboxlist name="hh" list="hobby1" value="hobby2"></s:checkboxlist> <br>
                                            
                                            
                                            <hr/>
                                            


                                            <s:checkboxlist name="province1" list="#{'0':'北京','1':'上海','2':'深圳'}" value="'2'"></s:checkboxlist>  <br>
                                            <s:checkboxlist name="province2" list="#{'北京':'0','上海':'1','深圳':'2'}" listKey="value" listValue="key" value="{'1'}"></s:checkboxlist>  <br>                              


                                            
                                            <hr/>
  
                                            <s:radio list="#{'0':'女','1':'男'}" value="'0'"></s:radio>  <br/>
                                            <s:radio list="#{'0':'女','1':'男'}" value="'1'"></s:radio>  <br/>
                                            <s:radio list="#{'0':'女','1':'男'}" listKey="key" listValue="value"></s:radio>  <br/>
                                            
                                            <hr/>
                                                                                     
                                            <s:select list="#{'0':'北京','1':'上海','2':'深圳'}" value="'1'"></s:select> <br/>
                                            <s:select list="#{'0':'北京','1':'上海','2':'深圳'}" value="'2'"></s:select> <br/>
                                            <s:select list="#{'0':'北京','1':'上海','2':'深圳'}" listKey="key" listValue="value"></s:select> <br/>
                                                                          
                                            <hr/>                                     
                                            
                                            <s:form action="a11" namespace="/xxx">
                                              用户名: <s:textfield name="用户名"></s:textfield>
                                              密码:   <s:password name="password"></s:password>
                                            </s:form>
                                            


                                      </body>
                                
                                


                
                
五、防止表单重复提交


        步骤:   
            1. 在表单中加入<s:token/>标签
            2. 在配置文件中的action中加入token的拦截器
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <interceptor-ref name="token"></interceptor-ref>  
            3. 并在配置文件中的action中增加一个名称为invalide.token的结果集        
                    <result name="invalid.token">/noSubmitMany/success.jsp</result>
                    
                    
         例:        
            **************************************************************************************************
            
            请求页面:
                <body>  
                    <!-- 访问地址:  http://localhost:8080/struts2day03/noSubmitMany/addCustomer.jsp -->  
                    <form action="addCustomer" namespace="/noSubmitMany">
                        <s:token></s:token> <!-- 防止表单重复提交步骤1: 添加s:token标签 -->
                        <s:textfield name="username" label="用户名"></s:textfield> <br/>
                        <s:submit value="保存"></s:submit>
                    </form>
                </body>
            
            配置文件:
                <package name="noSubmitMany" namespace="/noSubmitMany" extends="struts-default">
                  <action name="addCustomer" class="cn.itcast.action.AddCustomerAction" method="add">  
                    
                      <!-- 防止表单重复提交步骤2 创建拦截器 -->    
                      <interceptor-ref name="defaultStack"></interceptor-ref>
                      <interceptor-ref name="token"></interceptor-ref>  
                      
                      <!-- 防止表单重复提交步骤3 创建结果集   注:name="invalid.token" -->  
                      <result name="invalid.token">/noSubmitMany/success.jsp</result>
                    
                      <result name="success">/noSubmitMany/success.jsp</result>
                      
                  </action>
                </package>


              
            Action类:
                public class AddCustomerAction extends ActionSupport implements Serializable {
                  private String username;
                  // set/get属性
                  
                  public String add(){
                      System.out.println("添加成功!");
                      return SUCCESS;
                  }
                }
                
            JSP:
                 <body>
                     ${message}    
                 </body>
            
            
            **************************************************************************************************
          
          
          
六、 如何使用Struts的插件。(牵扯与其他框架整合)JFreeChart整合


      使用标准插件:JFreeChart使用
            
      图形的选择:  将jfreechart-1.0.13整个文件夹拷到C盘下,运行         
                    java -jar C:\jfreechart-1.0.13\jfreechart-1.0.13-demo.jar
                  即可打开图形,拷贝里面的源码到动作类中,即可
      最小jar包:
            struts2-jfreechart-plugin-2.1.8.1.jar
            jcommon-1.0.16.jar
            jfreechart-1.0.13.jar
            
      动作类
            public class GetChartAction extends ActionSupport {


                private static final long serialVersionUID = -7814290464584999876L;
                private JFreeChart chart;


                public JFreeChart getChart() {
                        return chart;
                }
                public String execute(){
                        ValueAxis xAxis = new NumberAxis("年度");
                        ValueAxis yAxis = new NumberAxis("产值");
                        XYSeries xySeries = new XYSeries("绿豆");
                        xySeries.add(0,300);
                        xySeries.add(1,200);
                        xySeries.add(2,400);
                        xySeries.add(3,500);
                        xySeries.add(4,600);
                        xySeries.add(5,500);
                        xySeries.add(6,800);
                        xySeries.add(7,1000);
                        xySeries.add(8,1100);
                        XYSeriesCollection xyDataset = new XYSeriesCollection(xySeries);
                        XYPlot xyPlot = new XYPlot(xyDataset,xAxis,yAxis,new StandardXYItemRenderer(StandardXYItemRenderer.SHAPES_AND_LINES));
                        chart = new JFreeChart(xyPlot);
                        return SUCCESS;
                }
            }
              
              
      配置文件:
            <!-- extends内容查看:  WEB-INF/lib/struts2-jfreechart-plugin-2.1.8.1.jar/struts-plugin.xml-->
            <package name="p2" extends="jfreechart-default">
                <action name="chart" class="wiva.struts2.train.action.GetChartAction">
                    <result type="chart">
                        <param name="width">600</param>
                        <param name="height">400</param>
                    </result>
                </action>
              </package>
              
              
      页面
            <body>
                <s:url action="chart" var="url"></s:url>
                <img src="<s:property value="url"/>" alt="hello" />

            </body>



























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值