zoukankan      html  css  js  c++  java
  • 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. 下载文件

  • 相关阅读:
    Codeforces Round #592 (Div. 2)C. The Football Season(暴力,循环节)
    Educational Codeforces Round 72 (Rated for Div. 2)D. Coloring Edges(想法)
    扩展KMP
    poj 1699 Best Sequence(dfs)
    KMP(思路分析)
    poj 1950 Dessert(dfs)
    poj 3278 Catch That Cow(BFS)
    素数环(回溯)
    sort与qsort
    poj 1952 buy low buy lower(DP)
  • 原文地址:https://www.cnblogs.com/lizhonghua34/p/4915192.html
Copyright © 2011-2022 走看看