网站开发常用的流程,服装公司网站模版,wordpress安装中文,a word与the wordpressJava工具类——通过配置XML验证Map 背景 在JavaWeb项目中#xff0c;接收前端过来的参数时通常是使用我们的实体类进行接收的。但是呢#xff0c;我们不能去决定已经搭建好的框架是怎么样的#xff0c;在我接触的框架中有一种就是通过Map来接收前端过来的所有参数#xff0…Java工具类——通过配置XML验证Map 背景 在JavaWeb项目中接收前端过来的参数时通常是使用我们的实体类进行接收的。但是呢我们不能去决定已经搭建好的框架是怎么样的在我接触的框架中有一种就是通过Map来接收前端过来的所有参数框架中没有实体类的说法从接收参数验证参数到参数至持久层整个过程都是通过Map来传递数据。 而在开发的过程中减少了实体类的存在有时是感觉挺方便的比如一个系统中有100多个表这里我们可以减少工作量虽然对应表的实体可以代码生成因为我们开发过程中是需要返回多个表关联后的结果的这里可能我们需要创建DTO这些步骤确实是挺烦人的。但是前端过来的参数我们需不需要验证呢客户的输入不管有意或者是无意我认为都应该让系统的容错能力更强悍一些。所以在验证前端过来的参数时使用了Map就着实让人头痛。每个需要强制验证的参数都需要get然后判断类型强制转型判断参数符不符合期望值边界等。 所以我就考虑了实体类可以通过Spring MVC中Hibernate的Validation使用注解的方式进行参数校验那么少了实体类我是不是可以通过配置XML的方式来达到类似有实体类的效果。网上找了类似关键词的工具类发现没有我所期望的所以就动手来了一个。 大致的想法 在Web开发时有许多if-else语句的出现都是在为了验证前端参数合不合法真的是挺无奈的而且有些代码虽然长起来类似但是呢要去重构成一个公用的方法好像有些困难时常问自己要怎么去搞Java不是JavaScript语句没那么灵活。 于是想着通过XML配置试试大致就是通过配置好的XML代替我们的实体类并且有个入口将XML中的实体映射并传入待验证的Map验证之后传出一个数组如果验证通过数组为空不通过则是我们XML中配置的对应错误语句。 如何设计XML格式 动手在这之前需要想好我们大致的XML结构是怎么样的。这里我的想法是在我们一般遇到的参数主要就是IntegerStringDoubleDateList了这里居然没有考虑Boolean算了之后再做补充也行。所以基于以上设计的结构大致如下 ?xml version1.0 encodingUTF-8?
map-verifyxmlnshttps://www.lger.cn/verifyxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttps://www.lger.cn/verify map-verify-util.xsd!--在长度的方面分别使用了lt; lte; gt; gte; eq;分别代表; ; ; ; --Entity nameUser01!--castErrMsg为当验证过程中类型解析错误时返回提示--String nameusername castErrMsgusername必须为字符串类型lengthlt errMsg当前值不能小于22/lt/lengthnotNull errMsg当前值不能为空/notBlank errMsg当前值不能为空去掉首尾空格/pattern!--如果不匹配则发出错误--value errMsg号码D[0-8]{4}[0-8]{4}/valuevalue errMsg号码D[0-7]{4}[0-7]{4}/value/pattern/StringInteger nameage castErrMsg必须为整型lt errMsg岁数必须大于22/ltgt150/gtnotNull//IntegerList namedetailsnotEmpty/sizegte0/gte/size!-- 遍历List内容遍历的Entity映射为name为User02的实体 --forEach entityUser02 //ListDate namebirthdaylt1900-07-21/ltnotNull//DateDouble namemoneylt1/ltgt150/gtnotNull//Double/EntityEntity nameUser02String nameusernamelengthlt errMsg当前值不能小于22/ltgt errMsg当前值不能大于1010/gt/lengthnotBlank errMsg当前值不能为空去掉空格//String/Entity
/map-verify需要写出一个具有一定格式的XML那么还需要写出一个约束文件了验证是否XML格式写的正确。这里还小学了一下XSD这里就不贴出代码了。 以上的XML大致的说了下怎么使用其替代实体类。写到了这里其实有时还觉得使用实体类可能更方便何必使用Map呢但是别人框架已经写了参数只能接收到Map那我只能屈服了。 类结构设计 首先每一个Entity就是一个实体对象这里我认为每个Entity都应该包含有一个验证方法和一个初始化方法因为在进行XML解析时就调用init在进行Map验证时就调用verify方法这样那些String节点也是类似的解析初始化时就把XML中配置的信息保存起来等到验证时就通过之前保存的信息进行判断即可不必重新解析了。 这里以解析一个IntegerEntity为例首先是其父类不论是XML中哪个节点都是实现VerifyEntity接口代码如下 public interface VerifyEntity {/*** 一个实体初始化当实体被创建时将由创建方主动调用* param currentEle 被创建的实体节点* param factory 实体创建工厂可以通过此工厂创建Entity*/void init(Element currentEle, EntityFactory factory);/*** 验证当前节点是否匹配XML的配置* param value 需要验证的值* return 异常字符串集*/String[] verify(Object value);/*** 初始化完毕后调用传入包含所有Entity的Map* param entityMap entityMap*/void finished(MapString, VerifyEntity entityMap);} 首先解析XML时当获取到Entity节点下的子节点将会通过一个工厂类创建子节点的对应实现VerifyEntity之后调用init方法对当前的子节点进行解析。这里先看下IntegerEntity的源码 public class IntegerEntity implements VerifyEntity {private AbstractEquationInteger integerEquation;private boolean notNull false;private String notNullErrMsg;private String castErrMsg;Overridepublic void init(Element currentEle, EntityFactory factory) {// 开始解析当前节点Integer/String name currentEle.attributeValue(name);// 获取节点属性castErrMsg看是否存在castErrMsgthis.castErrMsg currentEle.attributeValue(castErrMsg);if (Util.isEmpty(this.castErrMsg)) {this.castErrMsg name : this is not integer type.;} else {this.castErrMsg name : this.castErrMsg;}// 获取子节点notNullElement element currentEle.element(notNull);if (element ! null) {this.notNull true;this.notNullErrMsg element.attributeValue(errMsg);if (Util.isEmpty(this.notNullErrMsg)) {this.notNullErrMsg name : this is not null;} else {this.notNullErrMsg name : this.notNullErrMsg;}}// 这里是新建一个抽象的Equation类主要是因为lt和lte等等的这些节点在其他实体中也有为了代码复用所以使用了抽象类来定义//这里实现后与上面解析notNull代码差异不大integerEquation new AbstractEquationInteger(currentEle, name) {OverrideInteger valueOf(String value) {try {return Integer.valueOf(value);}catch (NumberFormatException e) {throw new ConvertException(castErrMsg);}}Overrideboolean lessThan(Integer value, Integer lt) {return value lt;}Overrideboolean greaterThan(Integer value, Integer gt) {return value gt;}Overrideboolean lessThanOrEquals(Integer value, Integer lte) {return value lte;}Overrideboolean greaterThanOrEquals(Integer value, Integer gte) {return value gte;}Overrideboolean equals(Integer value, Integer eq) {return value.equals(eq);}};}Overridepublic String[] verify(Object value) {//正式验证参数是否合法if (value null) {//如果之前解析包含notNull则这里为true那么将返回解析的notNullErrMsgif (this.notNull) {return new String[]{this.notNullErrMsg};}return null;}try {//使用上面实现的抽象类进行验证return integerEquation.verify(Integer.valueOf(value.toString()));}catch (NumberFormatException e) {return new String[]{this.castErrMsg};}}Overridepublic void finished(MapString, VerifyEntity entityMap) {//这里是在Entity解析完毕后调用并将保存Entity的Map传入}} 其实根据以上的代码可以看出就是XML的节点对应着一个VerifyEntity实现每一个实现都保存着其中定义的notNull/等信息。 实现后运行效果 这里我们的测试代码如下其中demo.xml为设计XML所示的代码 //初始化MapVerify将定义好xml以数组方式传入final String[] xmls {demo.xml};MapVerify.init(xmls);final MapString, Object map new HashMap(5);map.put(username, 12312371237123778);map.put(age, 1);map.put(birthday, 2000-07-21);map.put(money, 149);ListMapString, Object list new ArrayList(2);MapString, Object map1 new HashMap(1);map1.put(username, abcab);MapString, Object map2 new HashMap(1);map2.put(username, cc);list.add(map1);list.add(map2);map.put(details, list);System.out.println(Arrays.toString(MapVerify.verifyByReturnArr(User01, map))); 运行的结果如下 [age: 岁数必须大于2] 总结 此想法是半年前的了现在利用了空余的时间实现了自己的想法趁热打铁写下博客希望有这个需求的小伙伴能节省自己的时间注这里Boolean的判断没有实现如果有需要就需要自己动手了-。以后也希望自己如果有什么小想法尽量的抽时间去做不论做的好不好。 源码已经上传至 GitHub包含demo。 jar包请点击 此链接使用jar包时需要多引入dom4j依赖包 转载于:https://www.cnblogs.com/lger/p/10645453.html