• struts2笔记(3)


    关于回显:

    如果是int型,默认就会回显为0,如果不想让回显,则Integer就好

    //**************************************声明式验证**************************************

    如果配置文件xml没有提示,需要重新关联tdt:

    windows-preferences-xml-xml catalog,看里面有没有要关联的tdt,如果有,先移除再添加。add:

    key type : uri

    key : tdt路径

    然后从fire system中找

      1 1). 验证分为两种:
      2 
      3     > 声明式验证*
      4     
      5         >> 对哪个 Action 或 Model 的那个字段进行验证
      6         >> 使用什么验证规则
      7         >> 如果验证失败, 转向哪一个页面, 显示是什么错误消息
      8     
      9     > 编程式验证
     10     
     11 2). 声明式验证的 helloworld
     12 
     13 I.  先明确对哪一个 Action 的哪一个字段进行验证: age
     14 II. 编写配置文件: 
     15     > 把 struts-2.3.15.3appsstruts2-blankWEB-INFclassesexample 下的 Login-validation.xml 文件复制到
     16     当前 Action 所在的包下. 
     17     > 把该配置文件改为: 把  Login 改为当前 Action 的名字. 
     18     > 编写验证规则: 参见 struts-2.3.15.3/docs/WW/docs/validation.html 文档即可.
     19     > 在配置文件中可以定义错误消息: 
     20     
     21     <field name="age">
     22          <field-validator type="int">
     23              <param name="min">20</param>
     24              <param name="max">50</param>
     25              <message>^^Age needs to be between ${min} and ${max}</message>
     26          </field-validator>
     27      </field>
     28      
     29      > 该错误消息可以国际化吗. 可以
     30      
     31      <message key="error.int"></message>. 
     32      
     33             再在 国际化资源文件 中加入一个键值对: error.int=^^^Age needs to be between ${min} and ${max}
     34     
     35 III. 若验证失败, 则转向 input 的那个 result. 所以需要配置 name=input 的 result
     36      <result name="input">/validation.jsp</result>
     37      
     38 IV. 如何显示错误消息呢 ?      
     39 
     40     > 若使用的是非 simple, 则自动显示错误消息.
     41     > 若使用的是 simple 主题, 则需要 s:fielderror 标签或直接使用 EL 表达式(使用 OGNL)
     42     
     43     ${fieldErrors.age[0] } 
     44     OR
     45     <s:fielderror fieldName="age"></s:fielderror>*
     46 
     47 3). 注意: 若一个 Action 类可以应答多个 action 请求, 多个 action 请求使用不同的验证规则, 怎么办 ?
     48 
     49     > 为每一个不同的 action 请求定义其对应的验证文件: ActionClassName-AliasName-validation.xml(AliasName=actionname)
     50     
     51     > 不带别名的配置文件: ActionClassName-validation.xml 中的验证规则依然会发生作用. 可以把各个 action 公有的验证规则
     52     配置在其中. 但需要注意的是, 只适用于某一个 action 的请求的验证规则就不要这里再配置了. 
     53     
     54 4). 声明式验证框架的原理:
     55 
     56     > Struts2 默认的拦截器栈中提供了一个 validation 拦截器
     57     
     58     > 每个具体的验证规则都会对应具体的一个验证器. 有一个配置文件把验证规则名称和验证器关联起来了. 而实际上验证的是那个验证器. 
     59     该文件位于 com.opensymphony.xwork2.validator.validators 下的 default.xml
     60     
     61     <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
     62 
     63 5). 短路验证: 若对一个字段使用多个验证器, 默认情况下会执行所有的验证. 若希望前面的验证器验证没有通过, 后面的就不再验证, 可以使用短路验证
     64 
     65         <!-- 设置短路验证: 若当前验证没有通过, 则不再进行下面的验证 -->
     66         <field-validator type="conversion" short-circuit="true">
     67             <message>^Conversion Error Occurred</message>
     68         </field-validator>
     69 
     70         <field-validator type="int">
     71             <param name="min">20</param>
     72             <param name="max">60</param>
     73             <message key="error.int"></message>
     74         </field-validator>    
     75         
     76 6). 若类型转换失败, 默认情况下还会执行后面的拦截器, 还会进行 验证. 可以通过修改 ConversionErrorInterceptor 源代码的方式使
     77 当类型转换失败时, 不再执行后续的验证拦截器, 而直接返回 input 的 result
     78 
     79         Object action = invocation.getAction();
     80         if (action instanceof ValidationAware) {
     81             ValidationAware va = (ValidationAware) action;
     82 
     83             if(va.hasFieldErrors() || va.hasActionErrors()){
     84                 return "input";
     85             }
     86         }    
     87         
     88 7). 关于非字段验证: 不是针对于某一个字段的验证. 
     89 
     90     <validator type="expression">
     91         <param name="expression"><![CDATA[password==password2]]></param>
     92         <message>Password is not equals to password2</message>
     93     </validator>
     94      
     95           显示非字段验证的错误消息, 使用 s:actionerror 标签:  <s:actionerror/>
     96           
     97 8). 不同的字段使用同样的验证规则, 而且使用同样的响应消息 ?
     98 
     99 error.int=${getText(fieldName)} needs to be between ${min} and ${max}
    100 
    101 age=u5E74u9F84
    102 count=u6570u91CF       
    103 
    104 详细分析参见  PPT 159.  
    105 
    106 9). 自定义验证器:
    107 
    108 I.   定义一个验证器的类
    109 
    110     > 自定义的验证器都需要实现 Validator. 
    111     > 可以选择继承 ValidatorSupport 或 FieldValidatorSupport 类
    112     > 若希望实现一个一般的验证器, 则可以继承 ValidatorSupport
    113     > 若希望实现一个字段验证器, 则可以继承 FieldValidatorSupport
    114     
    115     > 具体实现可以参考目前已经有的验证器. 
    116     
    117     > 若验证程序需要接受一个输入参数, 需要为这个参数增加一个相应的属性
    118 
    119 II.  在配置文件中配置验证器
    120 
    121     > 默认情况下下, Struts2 会在 类路径的根目录下加载 validators.xml 文件. 在该文件中加载验证器.
    122          该文件的定义方式同默认的验证器的那个配置文件: 位于 com.opensymphony.xwork2.validator.validators 下的 default.xml
    123          
    124     > 若类路径下没有指定的验证器, 则从 com.opensymphony.xwork2.validator.validators 下的 default.xml 中的验证器加载     
    125 
    126 III. 使用: 和目前的验证器一样. 
    127 
    128 IV. 示例代码: 自定义一个 18 位身份证验证器    
    129 
    130 Struts2 的验证
    struts2的验证笔记

    短路验证:

    如果一个输入会导致多个错误提示,这个时候我们想要的是,显示一个错误,如果这个错误解决了还有错误,则显示下面的错误,这个时候就用到了短路验证。

    <validator  …/> 元素和 <field-validator  …/> 元素可以指定一个可选的 short-circuit 属性,该属性指定该验证器是否是短验证器,默认值为 false。

    对同一个字段内的多个验证器,如果一个短路验证器验证失败,其他验证器不会继续校验

    如果不想要某种验证,比如验证拦截器,可以修改上个拦截器的源码,不让走下面的拦截器,直接返回某个result

    比如验证两次密码相同:

    首先继承validationAware,有input这个result,在页面上有<s:actionerror/>  来显示,有验证的xml文件。

    他不是字段验证,而是非字段验证,是actionerrors,所以需要在页面上加上<s:actionerror/>  才会出现错误提示

    自定义验证器,参考其他已经有的验证器就行

    自定义一个 18 位身份证验证器
    1、编写验证器类
    2、在 validators.xml 文件中进行注册
    3、在验证配置文件中使用

    **************************************声明式验证**************************************//

    //**************************************文件的上传下载**************************************

    表单要作的准备如下:

    要想使用 HTML 表单上传一个或多个文件
    须把 HTML 表单的 enctype 属性设置为 multipart/form-data
    须把 HTML 表单的method 属性设置为 post
    需添加 <input type=“file”> 字段.

    1 <s:form action="" method="post" enctype="multipart/form-data">
    2     <s:file name="ppt" label="pptFile"></s:file>
    3     <s:textfield name="desc" label="desc"></s:textfield>
    4     <s:submit></s:submit>
    5 </s:form>
    上传页面示例

     文件上传和下载或许可以有这样的用途:

    动态加载数据,或者提供热更,比如需要更换数据的时候,我就从指定路径去搜索文件,我上传文件覆盖即可。

    1 ServletContext servletContext = ServletActionContext.getServletContext();
    2 String dir = servletContext.getRealPath("/files/" + fileName);//根目录下的文件
    获取服务器根目录下的路径
      1 1. 文件的上传:
      2 
      3 1). 表单需要注意的 3  4 
      5 2). Struts2 的文件上传实际上使用的是 Commons FileUpload 组件, 所以需要导入
      6 
      7 commons-fileupload-1.3.jar
      8 commons-io-2.0.1.jar
      9 
     10 3). Struts2 进行文件上传需要使用 FileUpload 拦截器
     11 
     12 4). 基本的文件的上传: 直接在 Action 中定义如下 3 个属性, 并提供对应的 getter 和 setter
     13 
     14 //文件对应的 File 对象
     15 private File [fileFieldName];
     16 //文件类型
     17 private String [fileFieldName]ContentType;
     18 //文件名
     19 private String [fileFieldName]FileName;
     20 
     21 5). 使用 IO 流进行文件的上传即可. 
     22 
     23 6). 一次传多个文件怎么办 ?
     24 
     25 若传递多个文件, 则上述的 3 个属性, 可以改为 List 类型! 多个文件域的 name 属性值需要一致. 
     26 
     27 7). 可以对上传的文件进行限制吗 ? 例如扩展名, 内容类型, 上传文件的大小 ? 若可以, 则若出错, 显示什么错误消息呢 ? 消息可以定制吗 ? 
     28 
     29 可以的!
     30 
     31 可以通过配置 FileUploadInterceptor 拦截器的参数的方式来进行限制
     32 
     33 maximumSize (optional) - 默认的最大值为 2M. 上传的单个文件的最大值
     34 
     35 allowedTypes (optional) - 允许的上传文件的类型. 多个使用 , 分割
     36 
     37 allowedExtensions (optional) - 允许的上传文件的扩展名. 多个使用 , 分割.
     38 
     39 注意: 在 org.apache.struts2 下的 default.properties 中有对上传的文件总的大小的限制. 可以使用常量的方式来修改该限制
     40 
     41 struts.multipart.maxSize=2097152
     42 
     43 定制错误消息. 可以在国际化资源文件中定义如下的消息:
     44 
     45 struts.messages.error.uploading - 文件上传出错的消息
     46 
     47 struts.messages.error.file.too.large - 文件超过最大值的消息
     48 
     49 struts.messages.error.content.type.not.allowed - 文件内容类型不合法的消息
     50 
     51 struts.messages.error.file.extension.not.allowed - 文件扩展名不合法的消息
     52 
     53 问题: 此种方式定制的消息并不完善. 可以参考 org.apache.struts2 下的 struts-messages.properties, 可以提供更多的定制信息.
     54 
     55 2. 文件的下载:
     56 
     57 1). Struts2 中使用 type="stream" 的 result 进行下载即可
     58 
     59 2). 具体使用细节参看 struts-2.3.15.3-all/struts-2.3.15.3/docs/WW/docs/stream-result.html
     60 
     61 3). 可以为 stream 的 result 设定如下参数
     62 
     63 contentType: 结果类型
     64 contentLength: 下载的文件的长度
     65 contentDisposition: 设定 Content-Dispositoin 响应头. 该响应头指定接应是一个文件下载类型, 一般取值为  attachment;filename="document.pdf".
     66 
     67 inputName: 指定文件输入流的 getter 定义的那个属性的名字. 默认为 inputStream
     68 
     69 bufferSize: 缓存的大小. 默认为 1024
     70 allowCaching: 是否允许使用缓存 
     71 contentCharSet: 指定下载的字符集 
     72 
     73 4). 以上参数可以在 Action 中以 getter 方法的方式提供!
     74 
     75 3. 表单的重复提交问题
     76 
     77 1). 什么是表单的重复提交
     78 
     79     > 在不刷新表单页面的前提下: 
     80         >> 多次点击提交按钮
     81         >> 已经提交成功, 按 "回退" 之后, 再点击 "提交按钮".
     82         >> 在控制器响应页面的形式为转发情况下,若已经提交成功, 然后点击 "刷新(F5)"
     83         
     84     > 注意:
     85         >> 若刷新表单页面, 再提交表单不算重复提交
     86         >> 若使用的是 redirect 的响应类型, 已经提交成功后, 再点击 "刷新", 不是表单的重复提交
     87         
     88 2). 表单重复提交的危害:              
     89 
     90 3). Struts2 解决表单的重复提交问题:
     91 
     92 I. 在 s:form 中添加 s:token 子标签
     93 
     94     > 生成一个隐藏域
     95     > 在 session 添加一个属性值
     96     > 隐藏域的值和 session 的属性值是一致的. 
     97     
     98 II. 使用 Token 或 TokenSession 拦截器. 
     99 
    100     > 这两个拦截器均不在默认的拦截器栈中, 所以需要手工配置一下
    101     > 若使用 Token 拦截器, 则需要配置一个 token.valid 的 result
    102     > 若使用 TokenSession 拦截器, 则不需要配置任何其它的 result
    103     
    104 III. Token VS TokenSession
    105 
    106     > 都是解决表单重复提交问题的
    107     > 使用 token 拦截器会转到 token.valid 这个 result
    108     > 使用 tokenSession 拦截器则还会响应那个目标页面, 但不会执行 tokenSession 的后续拦截器,不会执行目标action方法. 就像什么都没发生过一样!
    109     
    110 IV. 可以使用 s:actionerror 标签来显示重复提交的错误消息. 
    111 该错误消息可以在国际化资源文件中覆盖. 该消息可以在 struts-messages.properties 文件中找到
    112 
    113 struts.messages.invalid.token=^^The form has already been processed or no token was supplied, please try again.
    114 
    115 4. 自定义拦截器
    116 
    117 1). 具体步骤
    118 
    119 I. 定义一个拦截器的类
    120 
    121     > 可以实现 Interceptor 接口
    122     > 继承 AbstractInterceptor 抽象类
    123 
    124 II. 在 struts.xml 文件配置.    
    125 
    126     <interceptors>
    127             
    128         <interceptor name="hello" class="com.atguigu.struts2.interceptors.MyInterceptor"></interceptor>
    129         
    130     </interceptors>
    131     
    132     <action name="testToken" class="com.atguigu.struts2.token.app.TokenAction">
    133         <interceptor-ref name="hello"></interceptor-ref>
    134         <interceptor-ref name="defaultStack"></interceptor-ref>
    135         <result>/success.jsp</result>
    136         <result name="invalid.token">/token-error.jsp</result>
    137     </action>
    138     
    139 III. 注意: 在自定义的拦截器中可以选择不调用 ActionInvocation 的 invoke() 方法. 那么后续的拦截器和 Action 方法将不会被调用.
    140 Struts 会渲染自定义拦截器 intercept 方法返回值对应的 result
    View Code

    **************************************文件的上传下载**************************************//

    这个博客主要是javaEE相关或者不相关的记录, hadoop与spark的相关文章我写在下面地址的博客啦~ http://www.cnblogs.com/sorco
  • 相关阅读:
    python使用multiprocessing进行多进程编程(1)
    python使用multiprocessing进行多进程编程(1)
    最佳日志实践
    最佳日志实践
    最佳日志实践
    以大多数人的努力程度之低,根本轮不到去拼天赋
    以大多数人的努力程度之低,根本轮不到去拼天赋
    以大多数人的努力程度之低,根本轮不到去拼天赋
    C++Socket编程总结 [转]
    C++多线程的几个重要方法解析CreateEvent / SetEvent /ResetEvent/ 等
  • 原文地址:https://www.cnblogs.com/orco/p/6252745.html
Copyright © 2020-2023  润新知