8.3 集合类型输入校验介绍
于之前类型转化章节中记述的集合类型的对象类型转化相同。 Struts2 也支持集合类型的对象的输入校验。因此批量的对同一对象包含的属性数据的输入校验也是笔者需要向读者说明的,读者可以于类型转化中相关章节一起对照来学习。
8.3.1 Struts2 中单个 Java 对象的输入校验形式
技术要点 在介绍集合类型的输入校验之前,必须向读者介绍单个 Java 对象输入校验的形式。因为每个集合类型中包含的元素都是一个个单独的 java 对象,因此 Java 对象的输入校验是集合类型对象数据输入校验的基础。请读者必须要掌握。
Visitor 校验器的介绍和使用方式。
Action 和 Java 对象的输入校验配置文件介绍。
演示代码
还是使用第七章的添加材料那个示例。具体的 Material 对象代码和第七章相同。 Action 代码如下:
- <!---------------文件名:AddMaterialAction.java--------------->
- …………
- public class AddMaterialAction extends ActionSupport {
- //属性类型需要输入校验的材料对象
- private Material material;
- public Material getMaterial() {
- return material;
- }
- public void setMaterial(Material material) {
- this .material = material;
- }
- public String execute() throws Exception {
- return SUCCESS;
- }
- }
<!---------------文件名:AddMaterialAction.java---------------> ………… public class AddMaterialAction extends ActionSupport { //属性类型需要输入校验的材料对象 private Material material; public Material getMaterial() { return material; } public void setMaterial(Material material) { this.material = material; } public String execute() throws Exception { return SUCCESS; } }
添加材料和显示添加材料成功的 JSP 视图界面代码也和第七章相同。修改 Action 的输入校验配置文件 AddMaterialAction-validation.xml 文件,代码如下:
- <!-------------文件名:AddMaterialAction-validation.xml------------->
- <validators>
- <field name= "material" >
- <!- -单个JAVA对象校验 -->
- <field-validator type= "visitor" >
- <param name= "context" >materialContext</param>
- <param name= "appendPrefix" > true </param>
- <message>添加材料输入校验:</message>
- </field-validator>
- </field>
- </validators>
<!-------------文件名:AddMaterialAction-validation.xml-------------> <validators> <field name="material"> <!- -单个JAVA对象校验 --> <field-validator type="visitor"> <param name="context">materialContext</param> <param name="appendPrefix">true</param> <message>添加材料输入校验:</message> </field-validator> </field> </validators>
除了 Action 校验配置文件之外,本示例中还要增加 1 个对于 Material 这个 Java 对象的输入校验配置文件,名字叫 Material-materialContext-validation.xml 。至于为什么取这个名字稍后在代码解释中将说明。代码如下:
- <!-------文件名:Material-materialContext-validation.xml---------->
- <validators>
- <field name= "material" >
- <! - - 校验材料是否输入- ->
- <field-validator type= "requiredstring" >
- <message>请输入材料名</message>
- </field-validator>
- </field>
- <field name= "bid" >
- <! - - 校验价格是否输入- ->
- <field-validator type= "double" >
- <param name= "minExclusive" > 0.1 </param>
- <message>请输入价格</message>
- </field-validator>
- </field>
- <field name= "mount" >
- <! - - 校验库存量是否输入- ->
- <field-validator type= "int" >
- <param name= "min" > 1 </param>
- <message>请输入库存量</message>
- </field-validator>
- </field>
- <field name= "expireDate" >
- <! - - 校验过期日期是否输入- ->
- <field-validator type= "required" >
- <message>请输入过期日期</message>
- </field-validator>
- <! - - 校验过期日期是否在指定日期范围内- ->
- <field-validator type= "date" >
- <param name= "min" > 2009 - 01 - 01 </param>
- <param name= "max" > 2019 - 01 - 01 </param>
- <message>输入过期日期无效</message>
- </field-validator>
- </field>
- </validators>
<!-------文件名:Material-materialContext-validation.xml----------> <validators> <field name="material"> <! - - 校验材料是否输入- -> <field-validator type="requiredstring"> <message>请输入材料名</message> </field-validator> </field> <field name="bid"> <! - - 校验价格是否输入- -> <field-validator type="double"> <param name="minExclusive">0.1</param> <message>请输入价格</message> </field-validator> </field> <field name="mount"> <! - - 校验库存量是否输入- -> <field-validator type="int"> <param name="min">1</param> <message>请输入库存量</message> </field-validator> </field> <field name="expireDate"> <! - - 校验过期日期是否输入- -> <field-validator type="required"> <message>请输入过期日期</message> </field-validator> <! - - 校验过期日期是否在指定日期范围内- -> <field-validator type="date"> <param name="min">2009-01-01</param> <param name="max">2019-01-01</param> <message>输入过期日期无效</message> </field-validator> </field> </validators>
注意:该输入校验配置文件要和 Material 这个 Java 对象的代码文件放在同一目录下。
笔者还增加了一个 struts.properties 文件,方便输入支持本示例的字符编码集 GB2312
代码如下:
- <!-------------文件名:struts.properties---------------------->
- #支持本地化的资源文件名定义
- struts.i18n.encoding=gb2312
<!-------------文件名:struts.properties----------------------> #支持本地化的资源文件名定义 struts.i18n.encoding=gb2312
如图 8.5 ,如果没有输入任何信息时候的输入校验错误信息提示。
图 8.5 输入校验发现数据没有进行任何输入
如果输入的过期日期不是 Material-materialContext-validation.xml 文件中定义的日期范围时候出错信息如图 8.6 。
图 8.6 输入校验发现日期不符合所定义的日期范围
代码解释
( 1 )其实本示例代码很多都和类型转换中复合类型对象的类型转换示例很相似。所不同的就是两个输入校验时候使用的 xml 文件。
( 2 )第 1 个文件是 Action 的校验文件。该文件里由于 Action 的私有变量是一个 Material 对象。因此代码中 fieldname 是该变量名字,定义了 2 个参数。 1 个是 context 参数,所定义的名字是有开发者自己自由定义。但是之后 Material 对象的输入校验配置文件名字中必须有这个名字。而 appendPrefix 参数缺省是 false, 定义为 true 时候则表明在输入校验出错信息之前可以加上 message 所定义内容。图 8.5 和图 8.6 也显示了每个出错信息前都有 message 中定义的“添加材料输入校验:”这几个字,其原因就是笔者把 appendPrefix 参数设置了 true 才会有这样的效果。
( 3 )第 2 个文件是本示例重点,这个输入校验配置文件名字命名格式是“ Java 对象名 -context 参数 -validation.xml ”。在本示例中就是“ Material-materialContext-validation.xml ”。而且之前也已经说了该文件一定要和 Java 对象的类代码文件放在同一目录下。其中对输入校验规则的定义和前几节类似。都是使用了 Struts2 内置的输入校验器。其中用到了 1 个前几节没有用到的 double 类型,在之后小节会综合 Struts2 内置的输入校验器一起说明。
8.3.2 Struts2 对象集合即批量输入的校验形式
技术要点
Struts2 中也支持对 List 、 Set 等数据集合的输入校验。在视图页面上即是对同一 Java 对象进行批量的输入。这里笔者值介绍 List 数据集合类型的校验。其他数据集合类型校验依此类推。
批量输入校验格式和相关注意点。
演示代码
其实和上一小节代码是相同的。这里只将不同的代码罗列出来。支持 List 类型转换的属性文件如下:
- <!-----------文件名:AddMaterialAction-conversion.properties----------->
- #集合属性-List类型
- Element_materialList=com.model.Material
<!-----------文件名:AddMaterialAction-conversion.properties-----------> #集合属性-List类型 Element_materialList=com.model.Material
Action 代码如下:
- <!-------------文件名:AddMaterialAction.java--------------->
- public class AddMaterialAction extends ActionSupport {
- private List<Material> materialList;
- public String execute() throws Exception {
- return SUCCESS;
- }
- public List<Material> getMaterialList() {
- return materialList;
- }
- public void setMaterialList(List<Material> materialList) {
- this .materialList = materialList;
- }
- }
<!-------------文件名:AddMaterialAction.java---------------> public class AddMaterialAction extends ActionSupport { private List<Material> materialList; public String execute() throws Exception { return SUCCESS; } public List<Material> getMaterialList() { return materialList; } public void setMaterialList(List<Material> materialList) { this.materialList = materialList; } }
输入的 JSP 视图界面代码如下:
- <!------------文件名:addMaterial.jsp------------------>
- <s:form id= "materialForm" action= "addMaterial" theme= "simple" >
- <table>
- <tr>
- <td>材料名</td>
- <td>价格</td>
- <td>库存量</td>
- <td>过期日期</td>
- </tr>
- <s:iterator value= "new int[4]" status= "m" >
- <tr>
- <td><s:textfield name= "%{'materialList['+#m.index+'].material'}" /></td>
- <td><s:textfield name= "%{'materialList['+#m.index+'].bid'}" /></td>
- <td><s:textfield name= "%{'materialList['+#m.index+'].mount'}" /></td>
- <td><s:datetimepicker name= "%{'materialList['+#m.index+'].expireDate'}" /></td>
- </tr>
- </s:iterator>
- <tr>
- <td colspan= "4" ><s:submit value= "提交" ></s:submit>
- </tr>
- </table>
- </s:form>
<!------------文件名:addMaterial.jsp------------------> <s:form id="materialForm" action="addMaterial" theme="simple"> <table> <tr> <td>材料名</td> <td>价格</td> <td>库存量</td> <td>过期日期</td> </tr> <s:iterator value="new int[4]" status="m"> <tr> <td><s:textfield name="%{'materialList['+#m.index+'].material'}" /></td> <td><s:textfield name="%{'materialList['+#m.index+'].bid'}" /></td> <td><s:textfield name="%{'materialList['+#m.index+'].mount'}" /></td> <td><s:datetimepicker name="%{'materialList['+#m.index+'].expireDate'}" /></td> </tr> </s:iterator> <tr> <td colspan="4"><s:submit value="提交"></s:submit> </tr> </table> </s:form>
输入校验显示出错信息如图 8.7
图 8.7 输入校验所有数据为输入时候的出错信息
代码解释
( 1 ) Action 中私有变量是个 List 类型的 Material 对象的集合。但是 Action 和 Material 对象的输入校验配置文件内容和前 1 小节相同。
( 2 ) AddMaterialAction-conversion.properties 文件定义了 List 的元素都是 Material 对象 ( 请读者翻阅 List 集合类型转换章节,回忆一下这么做的原因 ) 。
( 3 )批量输入材料的 JSP 视图界面由代码可知和前一章类型转换中界面相同。笔者在本章一开始就说明了类型转换其实也是输入校验的 1 种。从这里也可以佐证这 1 论点。在下 1 小节也有说明。
( 4 )图 8.7 显示了所有信息未输入时候的出错信息。表明批量输入校验的确是在起作用。