• struts2表单提单细节处理


    1. 上传文件

    大部分项目避免不了要上传文件.

    struts2提供了封闭的上传文件的入口, 网络上也存在大量的插件用于网页表单中上传文件.

    由于自己习惯用SSH框架, 所以介绍一下struts2中文件上传的要点.

    struts2对文件上传的格式,及上传文件的大小有很好的限制.

    #Constants
    #struts.locale=zh_CN
    struts.i18n.encoding=UTF-8
    struts.action.extension=,
    struts.objectFactory=spring
    struts.custom.i18n.resources=messages
    #1G
    struts.multipart.maxSize=1048576000
    struts.ui.theme=css_xhtml
    #struts.enable.SlashesInActionNames=true
    struts.devMode=false
    struts.i18n.reload=true
    struts.configuration.xml.reload=true
    struts.serve.static.browserCache=false
    struts.ui.theme=simple

    上传时的页面 DOM

    <s:file cssClass="doc" name="documents[0].actionFile" />

    这样上传的文件会自动map到对象的属性上, 或者我们使用File []fileArray来预存表单提交到action的文件队列.

    不过通过此方法上传的文件队列是没有文件类型和文件名的,且在服务器以临时文件存在, 而且我们仍需要对等的使用 String []fileArrayFileName来存取对应的文件名.当然还有ContentType.

    所以到了action阶段, 需要再对文件进行IO重写操作,以保证文件以正确的格式存在合适的地方.

    以下代码用于读取存文件.

    public static JSONObject handlerFileUpload(String dir, File file,
                String fileName) throws IOException {
            JSONObject jo = new JSONObject();
            String realpath = ServletActionContext.getServletContext().getRealPath(
                    dir);//获取根目录+存放目录
            System.out.println("realpath: " + realpath);
            File doc;
            if (file != null) {
                doc = new File(realpath, fileName);//创建文件
                if (!doc.exists()) {
                    if (!doc.getParentFile().exists()) {
                        doc.getParentFile().mkdirs();//判断目录
                    }
                    OutputStream os = new FileOutputStream(new File(realpath,
                            fileName));
                    InputStream is = new FileInputStream(file);
                    byte[] buf = new byte[1024];
                    int length = 0;
    
                    while (-1 != (length = is.read(buf))) {
                        os.write(buf, 0, length);//写文件
                    }
                    is.close();
                    os.close();
                }
                jo.put("size", "" + file.length() / 1000 / 1000.0);//获取文件信息
                jo.put("fileName", fileName);
                jo.put("type", new MimetypesFileTypeMap().getContentType(file));
            }
            System.err.println("file:" + jo);
            return jo;//返回文件信息Json
        }

    2. 上传图片

    上传图片使用了最新的Ueditor的文件上传功能, Ueditor是个强大的富文本编辑器,可以编辑HTML或者纯文本, 且能带格式,字体,字号,表格,段落,附件,插图,link.

    文件目录:

    基本上把

    WebContent/ueditor/jsp/lib

    下的jar包考到项目的lib下, 就可以使用啦.

    不过, 若需要配置上传的路径, 附件, 插图, 涂鸦, 文件, 视频的上传到指定路径则需要配置一个json文件: /WebContent/ueditor/jsp/config.json

    /* 上传图片配置项 */
        "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
        "imageFieldName": "upfile", /* 提交的图片表单名称 */
        "imageMaxSize": 2048000, /* 上传大小限制,单位B */
        "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
        "imageCompressEnable": true, /* 是否压缩图片,默认是true */
        "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
        "imageInsertAlign": "none", /* 插入的图片浮动方式 */
        "imageUrlPrefix": "", /* 图片访问路径前缀 */
        "imagePathFormat": "/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                                    /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
                                    /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
                                    /* {time} 会替换成时间戳 */
                                    /* {yyyy} 会替换成四位年份 */
                                    /* {yy} 会替换成两位年份 */
                                    /* {mm} 会替换成两位月份 */
                                    /* {dd} 会替换成两位日期 */
                                    /* {hh} 会替换成两位小时 */
                                    /* {ii} 会替换成两位分钟 */
                                    /* {ss} 会替换成两位秒 */
                                    /* 非法字符  : * ? " < > | */
                                    /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */

    需要注意的是根路径指向的是tomcat的webapps,并不是项目目录.

    页面调用:

    1. 引用js包
      <script type="text/javascript" src="../ueditor/ueditor.config.js"></script>
      <script type="text/javascript" src="../ueditor/ueditor.all.js"></script>
      <script type="text/javascript" src="../ueditor/lang/en/en.js"></script>
      <script type="text/javascript" src="../resources/Admin/js/imageUploadModel.js"></script>
    2. 页面DOM
      <img id="preview" alt="The picture is missing or still not upload" src="" class="bannerimg" />
      <s:textfield id="picture" name="headerImg" onclick="upImage()" cssClass="scanimg input-sm" />
      <button type="button" class="input-sm" href="javascript:void(0);" onclick="clearImage();">Clear Image</button>
    3. JS实现
      var _editor = UE.getEditor('upload_ue');
      _editor.ready(function() {
          // 设置编辑器不可用
          // _editor.setDisabled(); 这个地方要注意 一定要屏蔽
          // 隐藏编辑器,因为不会用到这个编辑器实例,所以要隐藏
          _editor.hide();
      
          // 侦听图片上传
          _editor.addListener('beforeinsertimage', function(t, arg) {
              // 将地址赋值给相应的input,只去第一张图片的路径
              var imgs = '';
              for ( var a in arg) {
                  imgs += arg[a].src + ',';
              }
              imgs.toString().replace(/(,$)/g,'')
              $("#picture").attr("value", arg[0].src);
              // 图片预览
              $("#preview").attr("src", arg[0].src);
          })
      
      });
      // 弹出图片上传的对话框
      function upImage() {
          var myImage = _editor.getDialog("insertimage");
          myImage.open();
      }
      
      //清除图片
      function clearImage() {
          $("#picture").attr("value", "");
          // 图片预览
          $("#preview").attr("src", "");
      }
      
      //预览图片功能
      $(".scanimg").hover(function() {
          $thisImg = $(this).prev("img");
          var imgObj = new Image();
          $widthU = $thisImg.css('width');
          $width = $widthU.substring(0, $widthU.indexOf('px'));
          $scanleft = $(this).position().left;
          $scantop = $(this).position().top;
          $thisImg.css({
              "left" : ($scanleft + $width * 1.4) + "px",
              "top" : ($scantop - $width / 3) + "px"
          });
          $thisImg.show();
      }, function() {
          $(this).prev("img").hide();
      });
    4. 预览css
      .scanimg {
          cursor: pointer;
      }
      
      .scanimg:HOVER {
          color: red;
          text-decoration: underline;
      }
      
      .bannerimg {
          display: none;
          position: absolute;
          width: 200px;
          min-height: 50px;
          background-color: rgba(66,139,202,1);
          /* min- 500px; */
          /* max- 600px; */
      }

    至此, 所有相关的要素准备完毕.

    预览样式:

    3. validation

    表单都需要验证,一般有三种方式来处理验证表单的问题

    1. jQuery validation.js来做
      $(document).ready(function() {
          $('#user').next().slideDown(0);
          validate();
      });
      
      function validate() {
          var rules = {
              email : {
                  required : true,
                  email : true,
                  uniquedEmail : true
              },
              username : {
                  required : true,
                  maxlength: 16
              },
              password : {
                  required : true,
                  rangelength : [ 8, 16 ]
              },
              company : {
                  required : true,
                  maxlength : 16
              }
          }
          formValidate.validate('myform', rules);
      }
      
      
      formValidate = {
          validate : function(formId, rules) {
              validateForm(formId, rules);
          }
      }
      
      function validateForm(formId, rules, message) {
          $('#' + formId)
                  .validate(
                          {
                              debug : true, // 调试模式取消submit的默认提交功能
                              errorClass : "error-msg", // 默认为错误的样式类为:error
                              focusInvalid : false, // 当为false时,验证无效时,没有焦点响应
                              onkeyup : false,
                              submitHandler : function(form) { // 表单提交句柄,为一回调函数,带一个参数:form
                                  form.submit(); // 提交表单
                              },
                              rules : rules,
                              messages : {
                                  password : {
                                      rangelength : 'The length of the password you input must be between 8 and 16 characters'
                                  },
                                  oldPwd : {
                                      rangelength : 'The length of the password you input must be between 8 and 16 characters'
                                  },
                                  newPwd : {
                                      rangelength : 'The length of the password you input must be between 8 and 16 characters'
                                  },
                                  confirmPwd : {
                                      rangelength : 'The length of the password you input must be between 8 and 16 characters'
                                  }
                              }
                          });
      }
      
      jQuery.validator.addMethod("tele", function(value, element) {
      
          var tel = /^d{3,4}-?d{7,9}$/;
      
          return this.optional(element) || (tel.test(value));
      
      }, "Please write right tele number");
      
      jQuery.validator.addMethod("uniquedEmail", function(value, element) {
          var dataJson = new Object();
          $.ajax({
              url : 'isRegEmailExist',
              type : 'post',
              data : {
                  email : value
              },
              async : false, // 默认为true 异步
              error : function() {
                  dataJson.status = 502;
              },
              success : function(data) {
                  dataJson = JSON.parse(data);
      
              }
          });
          return this.optional(element) || (dataJson.status == 200);
      }, "The email is existed, please input other one!");
      <s:form action="reg" method="post" enctype="multipart/form-data" id="myform">
      .error-msg {
          color: #ff0000;
      }

      上述的方式在于灵活多变,不便的地方也看到了,需要调用ajax来请求服务器验证,且不同的浏览器对ajax返回的内容有不同的解释.                                                                                                   默认校验规则
      (1)required:true                必输字段
      (2)remote:"check.php"      使用ajax方法调用check.php验证输入值
      (3)email:true                    必须输入正确格式的电子邮件
      (4)url:true                        必须输入正确格式的网址
      (5)date:true                      必须输入正确格式的日期 日期校验ie6出错,慎用
      (6)dateISO:true                必须输入正确格式的日期(ISO),例如:2009-06-23,1998/01/22 只验证格式,不验证有效性
      (7)number:true                 必须输入合法的数字(负数,小数)
      (8)digits:true                    必须输入整数
      (9)creditcard:                   必须输入合法的信用卡号
      (10)equalTo:"#field"          输入值必须和#field相同
      (11)accept:                       输入拥有合法后缀名的字符串(上传文件的后缀)
      (12)maxlength:5               输入长度最多是5的字符串(汉字算一个字符)
      (13)minlength:10              输入长度最小是10的字符串(汉字算一个字符)
      (14)rangelength:[5,10]      输入长度必须介于 5 和 10 之间的字符串")(汉字算一个字符)
      (15)range:[5,10]               输入值必须介于 5 和 10 之间
      (16)max:5                        输入值不能大于5
      (17)min:10                       输入值不能小于10 

    2. 编码方式校验

         1) Action一定要继承自ActionSupport 

           2) 针对某个要进行校验的请求处理方法编写一个 public void validateXxx()方法,在方法内部进行表单数据校验.

          3) 也可针对所有的请求处理方法编写public void validate()方法。

          4) 在校验方法中,可以通过addFieldError()方法来添加字段校验错误消息。

          5) 当校验失败时,Struts框架会自动跳转到name为input的Result页面。在校验失败页面中,可以使用<s:fielderror/>来显示错误消息

          6) 简单,灵活。但重用性不高。

    3. XML配置方式校验。在编码方式之前被执行。 

      1) 针对要校验的Action类,在同包下编写一个名为:Action类名-validation.xml校验规则文件。

      2) 在校验规则文件中添加校验规则:具体的校验器名,参数可参看Struts2的reference或Struts2的API。

      •   a) Field校验:针对Action类中每个非自定义类型的Field进行校验的规则。

      1.     <field name="要校验的Field名">
             <field-validator type="校验规则器名" short-circuit="是否要短路径校验(默认是false)">
                 <param name="校验器要使用的参数名">值</param>
                    <message>校验失败时的提示消息</message>
          </field-validator>
          <!-- 还可添加其它的校验规则 -->
         </field>
         
             b) 非Field校验:针对Action类的某些Field使用OGNL表达进行组合校验。
            <validator type="fieldexpression">
          <param name="fieldName">pwd</param>
             <param name="fieldName">pwd2</param>
             <param name="expression"><![CDATA[pwd==pwd2]]></param><!-- OGNL表达式 -->
             <message>确认密码和密码输入不一致</message>
         </validator>
         
             c) visitor校验:主要是用来校验Action类中的自定义类型Field。(针对使用模型驱动方式时)
               i) 在Action类的的校验规则文件中针对自定义类型Field使用visitor校验规则。
            <!-- 针对自定义Field使用visitor校验 -->
         <field name="user">
          <field-validator type="required" short-circuit="true">
                    <message>用户的信息必填</message><!-- 消息前缀 -->
          </field-validator>
          <field-validator type="visitor"><!-- 指定为visitor校验规则 -->
           <param name="context">userContext</param><!-- 指定本visitor校验的上下文名 -->
                    <param name="appendPrefix">true</param><!-- 是否要添加校验失败消息的前缀 -->
                    <message>用户的</message><!-- 消息前缀 -->
          </field-validator>
         </field>
            ii) 针对visitor的Field编写一个校验规则文件.文件名为: visitor字段类型名[-visitor校验的上下文名]-validation.xml. 例如: 本例中的文件名为User-userContext-validation.xml
                          注意: 此文件要存放到visitor字段类型所在的包下.
            iii) 在visitor的Field校验规则文件中针对要校验的Field添加校验规则.
           3) 在校验失败页面(名为input的result页面)中,可以使用<s:fielderror/>来显示错误消息。
           4) 默认情况下,XML的校验规则对Action中所有的请求处理方法生效.此时应该只针对每个要校验的请求处理方法指定校验。有两种方式:
              i) 只为Action中的指定方法指定校验规则文件,配置文件命名为:Action类型名-别名-validation.xml,
                              别名是要校验的方法对应的Action标签的name属性值。
                              如:UserAction在struts2.xml的配置为:
            <package name="my" extends="struts-default" namespace="/">
          <action name="user_*" class="com.javacrazyer.web.action.UserAction" method="{1}">
           <result name="success">/info.jsp</result>
           <result name="input">/user_{1}.jsp</result>
          </action>
            </package>              
                        ● UserAction中有registe方法和login方法,要对registe方法进行校验,则它的校验规则文件名为:UserAction-user_registe-validation.xml。
                         ● 如果使用visitor校验器,必需指定visitor校验的上下文名。
              ii) 在校验拦截器中指定要验证的方法。不太实用。
           <action name="user_*" class="com.javacrazyer.web.action.UserAction" method="{1}">
            <result name="success">/info.jsp</result>
            <result name="input">/user_{1}.jsp</result>
             <interceptor-ref name="defaultStack">
                <!-- 给校验拦截器指定不进行校验的方法列表:用逗号隔开 -->
                <param name="validation.excludeMethods">*</param>
                <!-- 给校验拦截器指定要进行校验的方法列表:用逗号隔开 -->
                <param name="validation.includeMethods">regist</param>
              </interceptor-ref>
           </action>
           5) 同时使用客户端校验和服务器端校验
              i) 设置<s:form>标签的validate属性:
                 false:默认值。校验框架只执行服务器端校验。
                 true:先执行客户端校验,然后再执行服务器端校验。
                 form标签会根据你在服务器端配置的验证规则生成对应的JavaScript验证代码。
                              目前支持的内置校验器:required、requiredstring、stringlength、regex validator、email、url、int、double
              ii) 不太好用,不建议使用。建议使用jQuery进行页面表单校验。
           6) 自定义校验器:
              i) 继承自FieldValidatorSupport抽象类。重写validate(Object obj)方法
              ii) 注册校验器类. 在应用程序的classpath下新建一校验器注册文件。名为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="校验器名" class="校验器类的全限定名"/> 
        </validators>
         

       4. Annotation方式校验: Struts2提供了注解的方式校验

      1.   1) @Validation 指明这个类或者接口将使用基于注解的校验。Struts2.1中已被标识为过时。
          2) @Validations() 在同一个方法上要使用多个注解校验时。
          3) @SkipValidation 指定某个方法不需要校验。否则所有方法都会使用校验。也可以在检验拦截器中使用validateAnnotatedMethodOnly
          4) 13个内置校验器的注解版本:(注:这些注解都只能用在方法级别上) 具体参数参见Struts2的API或Reference。
        @RequiredFieldValidator
        @RequiredStringValidator
        @StringLengthFieldValidator
        @IntRangeFieldValidator
        @DoubleRangeFieldValidator
        @DateRangeFieldValidator
        @ExpressionValidator
        @FieldExpressionValidator
        @RegexFieldValidator
        @EmailValidator
        @UrlValidator
        @VisitorFieldValidator
        @ConversionErrorFieldValidator

        acc_registe.jsp

        1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
          <%@ taglib uri="/struts-tags" prefix="s" %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
            <head>
              <title>Struts2中基于XML配置式的校验器使用示例</title>
            </head>
            <body>
          <h3>XML配置式校验器---注册页面</h3><hr/>
          
          <div style="color:red"><s:fielderror/></div>
          <form action="acc_registe.action" method="post">
              <table>
                  <tr>
                      <td>ID</td>
                      <td><input type="text" name="id" value="${param.id}"/></td>
                  </tr>
                  <tr>
                      <td>登录名</td>
                      <td><input type="text" name="name" value="${param.name}"/></td>
                  </tr>
                  <tr>
                      <td>密码</td>
                      <td><input type="password" name="pwd"/></td>
                  </tr>
                  <tr>
                      <td>重复密码</td>
                      <td><input type="password" name="pwd2"/></td>
                  </tr>
                  <tr>
                      <td>时间</td>
                      <td><input type="text" name="registed_date" value="${param.registed_date}"/></td>
                  </tr>
                  <tr>
                      <td>email</td>
                      <td><input type="text" name="email" value="${param.email}"/></td>
                  </tr>
                  <tr>
                      <td>考试成绩</td>
                      <td><input type="text" name="score" value="${param.score}"/></td>
                  </tr>
                  <tr>
                      <td colspan="2"><input type="submit" value=" 提交 "/></td>
                  </tr>
              </table>
          </form>
            </body>
          </html>

           

         src/struts.xml

          1. <?xml version="1.0" encoding="UTF-8" ?>
            <!DOCTYPE struts PUBLIC
                "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
                "http://struts.apache.org/dtds/struts-2.1.7.dtd">
            
            <struts>
                <!-- 请求参数的编码方式 -->
                <constant name="struts.i18n.encoding" value="UTF-8"/>
                <!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开 -->
                <constant name="struts.action.extension" value="action,do,go,xkk"/>
                <!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开  -->
                <constant name="struts.configuration.xml.reload" value="true"/>
                <!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开  -->
                <constant name="struts.devMode" value="false"/>
                <!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭  -->
                <constant name="struts.serve.static.browserCache" value="false" />
                <!-- 是否允许在OGNL表达式中调用静态方法,默认值为false -->
                <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
                
                <!-- 指定由spring负责action对象的创建 
                <constant name="struts.objectFactory" value="spring" />
                -->
                <!-- 是否开启动态方法调用 -->
                <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
                
                <package name="my" extends="struts-default" namespace="/">
                    <action name="acc_*" class="com.javacrazyer.web.action.AccountAction" method="{1}">
                        <result name="success">/info.jsp</result>
                        <result name="input">/acc_{1}.jsp</result>
                    </action>
                    
                </package>
                
            </struts>
            
              

        AccountAction.java
        package com.javacrazyer.web.action;
        
        import java.util.Date;
        
        import com.opensymphony.xwork2.ActionSupport;
        
        
        public class AccountAction extends ActionSupport {
            private static final long serialVersionUID = -1418893621512812472L;
            private Integer id;
            private String name;
            private String pwd;
            private String pwd2;
            private Double score;
            private Date registed_date;
            private String email;
            
            public String registe() throws Exception{
                System.out.println("registe-------------------");
                return SUCCESS;
            }
            
            public String login()throws Exception{
                return SUCCESS;
            }
            
            public Integer getId() {
                return id;
            }
            public void setId(Integer id) {
                this.id = id;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public Double getScore() {
                return score;
            }
            public void setScore(Double score) {
                this.score = score;
            }
            public Date getRegisted_date() {
                return registed_date;
            }
            public void setRegisted_date(Date registedDate) {
                registed_date = registedDate;
            }
            public String getEmail() {
                return email;
            }
            public void setEmail(String email) {
                this.email = email;
            }
        
            public String getPwd() {
                return pwd;
            }
        
            public void setPwd(String pwd) {
                this.pwd = pwd;
            }
        
            public String getPwd2() {
                return pwd2;
            }
        
            public void setPwd2(String pwd2) {
                this.pwd2 = pwd2;
            }
        }

        AccountAction-validation.xml [与AccountAction同目录]
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE validators PUBLIC 
            "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
              "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
        <validators>
            <!-- 字段校验 -->
            <field name="id">
                <field-validator type="required" short-circuit="true">
                    <message>ID必填的</message>
                </field-validator>
                <field-validator type="int">
                    <param name="min">20</param>
                    <param name="max">50</param>
                    <message>ID必须在 ${min} 到 ${max} 之间</message>
                </field-validator>
            </field>
            <field name="name">
                <field-validator type="requiredstring" short-circuit="true">
                    <message>姓名是必填的</message>
                </field-validator>
                <field-validator type="regex">
                    <param name="expression"><![CDATA[(^[a-zA-Z_]w{3,9}$)]]></param>
                    <message>姓名不合法</message>
                </field-validator>
            </field>
            <field name="pwd">
                <field-validator type="requiredstring" short-circuit="true">
                    <message>密码是必填的</message>
                </field-validator>
            </field>
            
            <!-- 非字段校验 -->
            <validator type="fieldexpression">
                <param name="fieldName">pwd</param>
                <param name="fieldName">pwd2</param>
                <param name="expression"><![CDATA[pwd==pwd2]]></param><!-- OGNL表达式 -->
                <message>确认密码和密码输入不一致</message>
            </validator>
            
            <field name="score">
                <field-validator type="double">
                     <param name="minInclusive">0.0</param>
                       <param name="maxInclusive">100.0</param>
                       <message>成绩必须在${minInclusive}和${maxInclusive}之间</message>
                </field-validator>
            </field>
            <field name="email" >
                <field-validator type="regex">
                     <param name="expression"><![CDATA[(^[_A-Za-z0-9-]+(.[_A-Za-z0-9-]+)*@([A-Za-z0-9-])+((.com)|(.cn)|(.net)|(.org)|(.info)|(.edu)|(.mil)|(.gov)|(.biz)|(.ws)|(.us)|(.tv)|(.cc)|(.aero)|(.arpa)|(.coop)|(.int)|(.jobs)|(.museum)|(.name)|(.pro)|(.travel)|(.nato)|(..{2,3})|(..{2,3}..{2,3}))$)]]></param>
                     <message>邮箱不合法</message>
                </field-validator>
            </field>
            
            <field name="registed_date">
                <field-validator type="date">
                     <param name="min">1970-01-01</param>
                     <param name="max">2019-01-01</param>
                     <message>注册日期不合法</message>
                </field-validator>
            </field>
        </validators>
        第二个示例:XML配置式校验器---登录和注册页面

        user_login.jsp

        [html]view plaincopy
        <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
        <%@ taglib uri="/struts-tags" prefix="s" %>
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
        <html>
          <head>
            <title>Struts2中基于XML配置式的校验器使用示例</title>
          </head>
          <body>
        <h3>XML配置式校验器---登录页面</h3><hr/>
        <div style="color:red"><s:fielderror/></div>
        <form action="user_login.action" method="post">
            <table>
                <tr>
                    <td>登录名</td>
                    <td><input type="text" name="user.name" value="${param['user.name']}"/></td>
                </tr>
                <tr>
                    <td>密码</td>
                    <td><input type="password" name="user.pwd"/></td>
                </tr>
                <tr><td colspan="2"><input type="submit" value=" 提交 "/></td></tr>
            </table>
        </form>
          </body>
        </html>
          
        user_registe.jsp

        [html]view plaincopy
        <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
        <%@ taglib uri="/struts-tags" prefix="s" %>
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
        <html>
          <head>
            <title>Struts2中基于XML配置式的校验器使用示例</title>
          </head>
          <body>
        <h3>XML配置式校验器---注册页面</h3><hr/>
        
        <div style="color:red"><s:fielderror/></div>
        <form action="user_registe.action" method="post">
            <table>
                <tr>
                    <td>ID</td>
                    <td><input type="text" name="user.id" value="${param['user.id']}"/></td>
                </tr>
                <tr>
                    <td>登录名</td>
                    <td><input type="text" name="user.name" value="${param['user.name']}"/></td>
                </tr>
                <tr>
                    <td>密码</td>
                    <td><input type="password" name="user.pwd"/></td>
                </tr>
                <tr>
                    <td>重复密码</td>
                    <td><input type="password" name="user.pwd2"/></td>
                </tr>
                <tr>
                    <td>时间</td>
                    <td><input type="text" name="user.registed_date" value="${param['user.registed_date']}"/></td>
                </tr>
                <tr>
                    <td>email</td>
                    <td><input type="text" name="user.email" value="${param['user.email']}"/></td>
                </tr>
                <tr>
                    <td>考试成绩</td>
                    <td><input type="text" name="user.score" value="${param['user.score']}"/></td>
                </tr>
                <tr>
                    <td colspan="2"><input type="submit" value=" 提交 "/></td>
                </tr>
            </table>
        </form>
          </body>
        </html>
        src/struts.xml
        [html]view plaincopy
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE struts PUBLIC
            "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
            "http://struts.apache.org/dtds/struts-2.1.7.dtd">
        
        <struts>
            <!-- 请求参数的编码方式 -->
            <constant name="struts.i18n.encoding" value="UTF-8"/>
            <!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开 -->
            <constant name="struts.action.extension" value="action,do,go,xkk"/>
            <!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开  -->
            <constant name="struts.configuration.xml.reload" value="true"/>
            <!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开  -->
            <constant name="struts.devMode" value="false"/>
            <!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭  -->
            <constant name="struts.serve.static.browserCache" value="false" />
            <!-- 是否允许在OGNL表达式中调用静态方法,默认值为false -->
            <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
            
            <!-- 指定由spring负责action对象的创建 
            <constant name="struts.objectFactory" value="spring" />
            -->
            <!-- 是否开启动态方法调用 -->
            <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
            
            <package name="my" extends="struts-default" namespace="/">
                <action name="user_*" class="com.javacrazyer.web.action.UserAction" method="{1}">
                    <result name="success">/info.jsp</result>
                    <result name="input">/user_{1}.jsp</result>
                </action>
            </package>
            
        </struts>

        UserAction.java

        [java]view plaincopy
        package com.javacrazyer.web.action;
        
        
        import com.javacrazyer.domain.User;
        import com.opensymphony.xwork2.ActionSupport;
        
        
        public class UserAction extends ActionSupport {
            private static final long serialVersionUID = -2554018432709689579L;
            private User user; //自定义类型Field
            
            
            
            public String registe() throws Exception{
                System.out.println("registe======================");
                return SUCCESS;
            }
            
            public String login() throws Exception{
                return SUCCESS;
            }
            /*
            public void validate(){
                System.out.println("调用validate方法");
            }
            
            //执行exceute方法前调用
            public void validateRegiste(){
                System.out.println("调用validateRegiste方法");
                String lname = user.getLoginname();
                 if(null != lname && !lname.trim().matches("[a-zA-Z_]\w{3,19}")){
                        this.addFieldError("loginname", "用户名不能为空,且只能由4-20个字母和数字组成");
                        //this.addActionError("用户名不能为空,且只能由4-20个字母和数字组成");
                }
            }
            
            public void validateLogin(){
                System.out.println("调用validateLogin方法");
            }
        */
            public User getUser() {
                return user;
            }
        
            public void setUser(User user) {
                this.user = user;
            }
            
        }
        UserAction-user_login-validation.xml

        [html]view plaincopy
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE validators PUBLIC 
            "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
              "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
        <validators>
            <!-- 针对自定义Field使用visitor校验 -->
            <field name="user">
                <field-validator type="required" short-circuit="true">
                    <message>用户的信息必填</message><!-- 消息前缀 -->
                </field-validator>
                <field-validator type="visitor">
                    <param name="context">userLoginContext</param><!-- 指定本visitor校验的上下文 -->
                    <param name="appendPrefix">true</param><!-- 是否要添加校验失败消息的前缀 -->
                    <message>用户的</message><!-- 消息前缀 -->
                </field-validator>
            </field>
        </validators>

        UserAction-user_registe-validation.xml
        [html]view plaincopy
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE validators PUBLIC 
            "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
              "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
        <validators>
            <!-- 针对自定义Field使用visitor校验 -->
            <field name="user">
                <field-validator type="required" short-circuit="true">
                    <message>用户的信息必填</message><!-- 消息前缀 -->
                </field-validator>
                <field-validator type="visitor">
                    <param name="context">userContext</param><!-- 指定本visitor校验的上下文 -->
                    <param name="appendPrefix">true</param><!-- 是否要添加校验失败消息的前缀 -->
                    <message>用户的</message><!-- 消息前缀 -->
                </field-validator>
            </field>
        </validators>

        第三个示例:注解方式校验器---注册页面

        acc2_registe.jsp
        [html]view plaincopy
        <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
        <%@ taglib uri="/struts-tags" prefix="s" %>
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
        <html>
          <head>
            <title>Struts2中基于Annotation配置式的校验器使用示例</title>
          </head>
          <body>
        <h3>Annotation配置式校验器---注册页面</h3><hr/>
        
        <div style="color:red"><s:fielderror/></div>
        <form action="acc2_registe.action" method="post">
            <table>
                <tr>
                    <td>ID</td>
                    <td><input type="text" name="id" value="${param.id}"/></td>
                </tr>
                <tr>
                    <td>登录名</td>
                    <td><input type="text" name="name" value="${param.name}"/></td>
                </tr>
                <tr>
                    <td>密码</td>
                    <td><input type="password" name="pwd"/></td>
                </tr>
                <tr>
                    <td>重复密码</td>
                    <td><input type="password" name="pwd2"/></td>
                </tr>
                <tr>
                    <td>时间</td>
                    <td><input type="text" name="registed_date" value="${param.registed_date}"/></td>
                </tr>
                <tr>
                    <td>email</td>
                    <td><input type="text" name="email" value="${param.email}"/></td>
                </tr>
                <tr>
                    <td>考试成绩</td>
                    <td><input type="text" name="score" value="${param.score}"/></td>
                </tr>
                <tr>
                    <td colspan="2"><input type="submit" value=" 提交 "/></td>
                </tr>
            </table>
        </form>
          </body>
        </html>

          


        src/struts.xml
        [html]view plaincopy
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE struts PUBLIC
            "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
            "http://struts.apache.org/dtds/struts-2.1.7.dtd">
        
        <struts>
            <!-- 请求参数的编码方式 -->
            <constant name="struts.i18n.encoding" value="UTF-8"/>
            <!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开 -->
            <constant name="struts.action.extension" value="action,do,go,xkk"/>
            <!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开  -->
            <constant name="struts.configuration.xml.reload" value="true"/>
            <!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开  -->
            <constant name="struts.devMode" value="false"/>
            <!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关闭  -->
            <constant name="struts.serve.static.browserCache" value="false" />
            <!-- 是否允许在OGNL表达式中调用静态方法,默认值为false -->
            <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
            
            <!-- 指定由spring负责action对象的创建 
            <constant name="struts.objectFactory" value="spring" />
            -->
            <!-- 是否开启动态方法调用 -->
            <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
            
            <package name="my" extends="struts-default" namespace="/">
                    <action name="acc2_*" class="com.javacrazyer.web.action.Account2Action" method="{1}">
                    <result name="success">/info.jsp</result>
                    <result name="input">/acc2_{1}.jsp</result>
                </action>
            </package>
            
        </struts>
        Account2Action.java
        [java]view plaincopy
        package com.javacrazyer.web.action;
        
        import java.util.Date;
        
        import org.apache.struts2.interceptor.validation.SkipValidation;
        
        import com.opensymphony.xwork2.ActionSupport;
        import com.opensymphony.xwork2.validator.annotations.FieldExpressionValidator;
        import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
        import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
        import com.opensymphony.xwork2.validator.annotations.Validations;
        import com.opensymphony.xwork2.validator.annotations.ValidatorType;
        
        /**
         * 使用注解来配置校验的示例
         *
         */
        public class Account2Action extends ActionSupport {
            private static final long serialVersionUID = -1418893621512812472L;
            private Integer id;
            private String name;
            private String pwd;
            private String pwd2;
            private Double score;
            private Date registed_date;
            private String email;
            
            
            @Validations(
                    requiredStrings={@RequiredStringValidator(fieldName="name",message="我的用户名是必须的",shortCircuit=true,trim=true,type=ValidatorType.FIELD),
                            @RequiredStringValidator(fieldName="pwd",message="我的密码是必须的",shortCircuit=true,trim=true,type=ValidatorType.FIELD)},
                    fieldExpressions={@FieldExpressionValidator(fieldName="pwd", message="两次密码不相同",expression="pwd==pwd2")},
                    regexFields={@RegexFieldValidator(expression="^[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-])+((\.com)|(\.cn)|(\.net)|(\.org)|(\.info)|(\.edu)|(\.mil)|(\.gov)|(\.biz)|(\.ws)|(\.us)|(\.tv)|(\.cc)|(\.aero)|(\.arpa)|(\.coop)|(\.int)|(\.jobs)|(\.museum)|(\.name)|(\.pro)|(\.travel)|(\.nato)|(\..{2,3})|(\..{2,3}\..{2,3}))$")}
            )
            public String registe() throws Exception{
                System.out.println("registe-------------------");
                return SUCCESS;
            }
            
            @SkipValidation
            public String login()throws Exception{
                return SUCCESS;
            }
            
            public Integer getId() {
                return id;
            }
            public void setId(Integer id) {
                this.id = id;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public Double getScore() {
                return score;
            }
            public void setScore(Double score) {
                this.score = score;
            }
            public Date getRegisted_date() {
                return registed_date;
            }
            public void setRegisted_date(Date registedDate) {
                registed_date = registedDate;
            }
            public String getEmail() {
                return email;
            }
            public void setEmail(String email) {
                this.email = email;
            }
        
            public String getPwd() {
                return pwd;
            }
        
            public void setPwd(String pwd) {
                this.pwd = pwd;
            }
        
            public String getPwd2() {
                return pwd2;
            }
        
            public void setPwd2(String pwd2) {
                this.pwd2 = pwd2;
            }
        }

    4. 过滤

    过滤的问题源于URLEncode/URLDecode。字符在从前端到后台, GET方式会自动将URL行Encode,这就会导致空格,加号等字符被转码,所以后台需要再次解码。不过大部分的时候,Encode后并非一定能正确的Decode成当初的字符,所以又出现了BASE64,POST方式的代替方案。

    5. 阻止浏览器自动填充password/username表单域

    6. 富文本编辑器

    7. namespace

    8.表单重复提交

    9. button/input/submit 提交的方式

    10. struts2 Action返回result方式处理

    11. 下载文件

  • 相关阅读:
    Tabs 选项卡插件(续)
    Menu 菜单插件
    jquery Star Rating - 星形评级插件
    Tabs 选项卡插件
    jQuery Tooltips插件
    jQuery信息提示插件(jQuery Tooltip Plugin)
    Accordion 手风琴 折叠菜单插件
    Calendars 日历插件
    Microsoft Windows 2000 professional(集成SP4)简体中文专业版下载
    俄罗斯商务资讯网(门户网站)
  • 原文地址:https://www.cnblogs.com/lizhonghua34/p/4915192.html
Copyright © 2020-2023  润新知