盱眙网站建设代理网络工具下载

当前位置: 首页 > news >正文

盱眙网站建设,代理网络工具下载,容桂做网站,外贸型网站制作直接上代码 1.是否启用参数校验注解 Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface EnableArgumentsCheck {/*** 是否启用/boolean enable() default true;} 2.参数校验自定义注解 /** 参数校验自定义注解* 属性定义#…直接上代码 1.是否启用参数校验注解 Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface EnableArgumentsCheck {/*** 是否启用/boolean enable() default true;} 2.参数校验自定义注解 /** 参数校验自定义注解* 属性定义* name 必填字段名称用于参数校验失败消息提示* range 非必填范围校验LongintDouble属性校验生效{0,500000000}* decimal 非必填Double类型校验decimal {5,2}校验参数为5位数保留2位小数* contain 非必填参数int,String校验{10,20,30}* isNotNull 非必填参数是否不能为空默认值false,使用所有类型* type 非必传适用String类型校验字段类型EMAILMOBILEIDENTITY_CARDNUMBERDATE* min 非必传LongintDouble属性校验最小值限制校验当前类型值不能小于min的值默认值Integer.MIN_VALUE* max 非必传LongintDouble属性校验最大值限制校验当前类型值不能大于max的值,默认值Integer.MAX_VALUE* pattern 非必传参数int,String正则表达式校验* enumClass 非必传枚举值校验判断当前值是否在枚举中enumClass和enumAttr一起使用适用Stringint* message 非必填错误消息提示默认字段xxx参数检验不合法* maxLength 非必传最大长度限制校验适用LongintDoublestringlistarrays* minLength 非必传最小长度限制校验适用LongintDoublestringlistarrays* like 非必传参数模糊匹配* groups 非必传分组匹配使用所有类型* formatDate 非必传时间格式参数验证适用string校验* division非必传校验时间是否将来时间还是过去时间future将来时间past过去时间适用date校验* author 106979/ Target({ElementType.FIELD, ElementType.PARAMETER}) Retention(RetentionPolicy.RUNTIME) Documented public interface PropertiesVerify {/** 字段名称* return/String name();/** 范围range* return/int[] range() default {};/** 小数类型长度和小数位数* return/int[] decimal() default {};/** 包含字符串* return/String[] contain() default {};/** 是否为空/boolean isNotNull() default false;/** 字段类型* return/FieldType type() default FieldType.NULL;/** Int最小值/int minInt() default Integer.MIN_VALUE;/** Int最大值/int maxInt() default Integer.MAX_VALUE;/** Long最小值/long minLong() default Long.MIN_VALUE;/** Long最大值/long maxLong() default Long.MAX_VALUE;/** 正则表达式/String pattern() default ;/** 枚举* return/Class? enumClass() default Void.class;/** 分组* return/Class? extends Default[] groups() default {};/** 枚举方法* return/String enumAttr() default ;/** 模糊匹配* return/String like() default ;/** 时间格式* return/String formatDate() default ;/** 最大长度* return/int maxLength() default -1;/** 最小长度* return/int minLength() default -1;/** 时间分割线* return/DateDivisionEnum division() default DateDivisionEnum.NONE;/** 错误消息提示* return/String message() default %s校验不通过,%s;enum FieldType {NULL(, ),EMAIL(邮箱, ^A-Za-z\d([A-Za-z\d][-.])[A-Za-z\d]{2,4}\(),MOBILE(手机号码, ^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(16[5,6])|(17[0-8])|(18[0-9])|(19[1、5、8、9]))\\\\d{8}\)),IDENTITYCARD(身份证, ^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([\\d|x|X]{1})\(),NUMBER(正整数, ^[0-9]*[1-9][0-9]*\)),DATE(日期, ((^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\.])(10|12|0?[13578])([-\/\.])(3[01]|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\.])(11|0?[469])([-\/\.])(30|[12][0-9]|0?[1-9])$)|(^((1[8-9]\d{2})|([2-9]\d{3}))([-\/\.])(0?2)([-\/\.])(2[0-8]|1[0-9]|0?[1-9])$)|(^([2468][048]00)([-\/\.])(0?2)([-\/\.])(29)$)|(^([3579][26]00)([-\/\.])(0?2)([-\/\.])(29)$)|(^([1][89][0][48])([-\/\.])(0?2)([-\/\.])(29)$)|(^([2-9][0-9][0][48])([-\/\.])(0?2)([-\/\.])(29)$)|(^([1][89][2468][048])([-\/\.])(0?2)([-\/\.])(29)$)|(^([2-9][0-9][2468][048])([-\/\.])(0?2)([-\/\.])(29)$)|(^([1][89][13579][26])([-\/\.])(0?2)([-\/\.])(29)$)|(^([2-9][0-9][13579][26])([-\/\.])(0?2)([-\/\._])(29)$)));public String name;public String regular;FieldType(String name, String regular) {this.name name;this.regular regular;}}}3.参数校验接口 /*** 参数校验接口* author zcs/ public interface ArgumentsVerify {/** 默认参数校验* return/String check(); } 4.参数校验抽象类提供基础校验方法以及继承抽象类的子类. public abstract class AbstractArgumentsVerify implements ArgumentsVerify {private static final String DECIMAL_POINT \.;private static final int ARRAY_LENGTH 2;protected Object inputData;protected PropertiesVerify propertiesVerify;protected Class? extends Default groups;AbstractArgumentsVerify(Object inputData, PropertiesVerify propertiesVerify, Class? extends Default groups) {this.inputData inputData;this.propertiesVerify propertiesVerify;this.groups groups;}/** 包含校验* return/public String isContain() {if (inputData ! null propertiesVerify ! null propertiesVerify.contain() ! null propertiesVerify.contain().length 0 !Arrays.asList(propertiesVerify.contain()).contains(inputData.toString())) {return getMsg(不存在指定值范围内);}return StringUtils.EMPTY;}/** 时间类型校验* return/public String isFormatDate() {if (inputData null) {return StringUtils.EMPTY;}if (StringUtils.isNotBlank(propertiesVerify.formatDate())) {Date d null;try {SimpleDateFormat sdf new SimpleDateFormat(propertiesVerify.formatDate(), Locale.CHINA);d sdf.parse(inputData.toString());} catch (ParseException e) {throw new RuntimeException(参数校验时间格式错误);}if (d null) {return getMsg(时间格式错误);}}return StringUtils.EMPTY;}/** 时间分界校验* return/public String division() {if (inputData null) {return StringUtils.EMPTY;}if (propertiesVerify.division() ! null !DateDivisionEnum.NONE.equals(propertiesVerify.division())) {Date d (Date) inputData;Date currentDate new Date();switch (propertiesVerify.division()) {case FUTURE:if (!d.after(currentDate)) {return getMsg(必须大于当前时间);}break;case PAST:if (!d.before(currentDate)) {return getMsg(必须小于当前时间);}break;}}return StringUtils.EMPTY;}/** 最小值参数校验* return/public String isMinInt() {if (inputData null) {return StringUtils.EMPTY;}int intVal 0;try {intVal (int) inputData;} catch (Exception e) {//非数字类型不校验}if (propertiesVerify.minInt() intVal) {return getMsg(输入值小于指定最小值);}return StringUtils.EMPTY;}/** 最大值* return/public String isMaxInt() {if (inputData null) {return StringUtils.EMPTY;}int intVal 0;try {intVal (int) inputData;} catch (Exception e) {//非数字类型不校验}if (propertiesVerify.maxInt() intVal) {return getMsg(输入值大于指定最大值);}return StringUtils.EMPTY;}/** 最小值参数校验* return/public String isMinLong() {if (inputData null) {return StringUtils.EMPTY;}long longVal 0;try {longVal (long) inputData;} catch (Exception e) {//非数字类型不校验}if (propertiesVerify.minLong() longVal) {return getMsg(输入值小于指定最小值);}return StringUtils.EMPTY;}/** 最大值* return/public String isMaxLong() {if (inputData null) {return StringUtils.EMPTY;}long longVal 0;try {longVal (long) inputData;} catch (Exception e) {//非数字类型不校验}if (propertiesVerify.maxLong() longVal) {return getMsg(输入值大于指定最大值);}return StringUtils.EMPTY;}/** 最小长度* return/public String minLength() {if (inputData null) {return StringUtils.EMPTY;}if (propertiesVerify.minLength() 0) {int length;length getLength();if (length propertiesVerify.minLength()) {return getMsg(输入值长度小于最小值);}}return StringUtils.EMPTY;}/** 最大长度* return/public String maxLength() {if (inputData null) {return StringUtils.EMPTY;}if (propertiesVerify.maxLength() 0) {int length;length getLength();if (length propertiesVerify.maxLength()) {return getMsg(输入值长度大于最大值);}}return StringUtils.EMPTY;}private int getLength() {int length;if (inputData instanceof Map) {Map mapData (Map) inputData;length mapData.size();} else if (inputData instanceof List) {List listData (List) inputData;length listData.size();} else if (inputData instanceof Collection) {Collection collectionData (Collection) inputData;length collectionData.size();} else if (inputData.getClass().isArray()) {length Arrays.asList(inputData).size();} else {length inputData.toString().length();}return length;}/** 取值范围* return/public String range() {if (inputData null) {return StringUtils.EMPTY;}BigDecimal b null;try {b new BigDecimal(inputData.toString());} catch (Exception e) {//非数字类型不校验}if (b ! null propertiesVerify.range() ! null propertiesVerify.range().length ARRAY_LENGTH (b.doubleValue() propertiesVerify.range()[1] || b.doubleValue() propertiesVerify.range()[0])) {return getMsg(String.format(输入值必须在%s-%s范围内, propertiesVerify.range()[0], propertiesVerify.range()[1]));}return StringUtils.EMPTY;}/** 模糊匹配* return/public String isLike() {if (inputData null) {return StringUtils.EMPTY;}if (StringUtils.isNotBlank(propertiesVerify.like()) !inputData.toString().contains(propertiesVerify.like())) {return getMsg(String.format(参数必须包含[%s], propertiesVerify.like()));}return StringUtils.EMPTY;}/** 字段类型枚举* return/public String type() {if (inputData null) {return StringUtils.EMPTY;}if (propertiesVerify.type() ! null StringUtils.isNotBlank(propertiesVerify.type().regular)) {Pattern pat Pattern.compile(propertiesVerify.type().regular);Matcher mat pat.matcher(inputData.toString());boolean isMatch mat.matches();if (!isMatch) {return getMsg(String.format(参数不匹配类型, propertiesVerify.type().name));}}return StringUtils.EMPTY;}/** 小数范围* return/public String decimal() {if (inputData null) {return StringUtils.EMPTY;}if (propertiesVerify.decimal() ! null propertiesVerify.decimal().length ARRAY_LENGTH) {//全部位数int digitsNumber propertiesVerify.decimal()[0];//小数位数int decimalNumber propertiesVerify.decimal()[1];String strVal inputData.toString().replace(-, );if (StringUtils.contains(strVal, .)) {int intLength strVal.split(DECIMAL_POINT)[0].length();int decimalLength strVal.split(DECIMAL_POINT)[1].length();if (intLength decimalLength digitsNumber) {return getMsg(String.format(参数不能超过%s位, digitsNumber));}if (decimalLength decimalNumber) {return getMsg(String.format(小数不能超过%s位, decimalNumber));}} else {int intLength strVal.length();if (intLength digitsNumber) {return getMsg(String.format(参数不能超过%s位, digitsNumber));}}}return StringUtils.EMPTY;}/** 自定义正则表达式* return/public String pattern() {if (inputData null) {return StringUtils.EMPTY;}if (StringUtils.isNotBlank(propertiesVerify.pattern())) {Pattern pat Pattern.compile(propertiesVerify.pattern());Matcher mat pat.matcher(inputData.toString());boolean isMatch mat.matches();if (!isMatch) {return getMsg(参数不满足正则表达式);}}return StringUtils.EMPTY;}/** 枚举值* return/public String enumVal() {if (inputData null) {return StringUtils.EMPTY;}if (propertiesVerify.enumClass() ! null propertiesVerify.enumClass() ! Void.class StringUtils.isNotBlank(propertiesVerify.enumAttr())) {try {// 2.得到所有枚举常量Object[] objects propertiesVerify.enumClass().getEnumConstants();String methodName get propertiesVerify.enumAttr().substring(0, 1).toUpperCase() propertiesVerify.enumAttr().substring(1);Method method propertiesVerify.enumClass().getMethod(methodName);boolean isInclude false;for (Object obj : objects) {// 3.调用对应方法得到枚举常量中字段的值Object val method.invoke(obj);if (val ! null inputData.toString().equals(val )) {isInclude true;break;}}if (!isInclude) {return getMsg(参数不在指定枚举值中);}} catch (Exception e) {//todo 异常处理System.out.println(e.getMessage());}}return StringUtils.EMPTY;}private String getMsg(String desc) {return String.format(propertiesVerify.message(), propertiesVerify.name(), desc);} }实现类型   public class DateArgumentsVerify extends AbstractArgumentsVerify {public DateArgumentsVerify(Date val, PropertiesVerify propertiesVerify, Class? extends Default groups) {super(val, propertiesVerify, groups);}Overridepublic String check() {String res super.division();if (StringUtils.isNotBlank(res)) {return res;}return StringUtils.EMPTY;} }public class DoubleArgumentsVerify extends AbstractArgumentsVerify {public DoubleArgumentsVerify(String val, PropertiesVerify propertiesVerify, Class? extends Default groups) {super(val, propertiesVerify, groups);}Overridepublic String check() {//包含校验String res super.maxLength();if (StringUtils.isNotBlank(res)) {return res;}res super.minLength();if (StringUtils.isNotBlank(res)) {return res;}res super.decimal();if (StringUtils.isNotBlank(res)) {return res;}res super.isLike();if (StringUtils.isNotBlank(res)) {return res;}res super.range();return res;} }public class IntegerArgumentsVerify extends AbstractArgumentsVerify {public IntegerArgumentsVerify(Integer val, PropertiesVerify propertiesVerify, Class? extends Default groups) {super(val, propertiesVerify, groups);}Overridepublic String check() {//包含校验String res super.isContain();if (StringUtils.isNotBlank(res)) {return res;}res super.maxLength();if (StringUtils.isNotBlank(res)) {return res;}res super.minLength();if (StringUtils.isNotBlank(res)) {return res;}//最小值校验res super.isMinInt();if (StringUtils.isNotBlank(res)) {return res;}res super.pattern();if (StringUtils.isNotBlank(res)) {return res;}res super.isLike();if (StringUtils.isNotBlank(res)) {return res;}res super.enumVal();if (StringUtils.isNotBlank(res)) {return res;}//最大值校验res super.isMaxInt();if (StringUtils.isNotBlank(res)) {return res;}res super.range();return res;} }public class ListArgumentsVerify extends AbstractArgumentsVerify {public ListArgumentsVerify(ListObject val, PropertiesVerify propertiesVerify, Class? extends Default groups) {super(val, propertiesVerify, groups);}Overridepublic String check() {//校验List类型参数String res super.minLength();if (StringUtils.isNotBlank(res)) {return res;}res super.maxLength();if (StringUtils.isNotBlank(res)) {return res;}if (CollectionUtils.isNotEmpty((Collection) super.inputData)) {for (Object obj : (Collection) super.inputData) {res ArgumentsCheckUtil.check(obj, super.groups);if (StringUtils.isNotBlank(res)) {break;}}}return res;} }public class LongArgumentsVerify extends AbstractArgumentsVerify {public LongArgumentsVerify(Long val, PropertiesVerify propertiesVerify, Class? extends Default groups) {super(val, propertiesVerify, groups);}Overridepublic String check() {String res super.maxLength();if (StringUtils.isNotBlank(res)) {return res;}res super.minLength();if (StringUtils.isNotBlank(res)) {return res;}res super.isLike();if (StringUtils.isNotBlank(res)) {return res;}//最小值校验res super.isMinLong();if (StringUtils.isNotBlank(res)) {return res;}//最大值校验res super.isMaxLong();if (StringUtils.isNotBlank(res)) {return res;}res super.range();return res;} }public class StringArgumentsVerify extends AbstractArgumentsVerify {public StringArgumentsVerify(String val, PropertiesVerify propertiesVerify, Class? extends Default groups) {super(val, propertiesVerify, groups);}Overridepublic String check() {//包含校验if(StringUtils.isBlank((String)inputData)){return ;}String res super.isContain();if (StringUtils.isNotBlank(res)) {return res;}res super.isLike();if (StringUtils.isNotBlank(res)) {return res;}res super.type();if (StringUtils.isNotBlank(res)) {return res;}res super.pattern();if (StringUtils.isNotBlank(res)) {return res;}res super.enumVal();if (StringUtils.isNotBlank(res)) {return res;}res super.maxLength();if (StringUtils.isNotBlank(res)) {return res;}res super.isFormatDate();if (StringUtils.isNotBlank(res)) {return res;}res super.minLength();return res;} }5.使用到的枚举 /** 时间检验分割线* author 106979/ public enum DateDivisionEnum {NONE(无),FUTURE(将来时间),PAST(过去时间);public String name;DateDivisionEnum(String name) {this.name name;} } 6.工具类: public class ArgumentsCheckUtil {/** 参数验证* param cla 需要校验的对象* return 校验异常消息/public static String check(Object cla) {return check(cla, null);}/** 参数验证* param cla 需要校验的对象* param groups 分组* return 校验异常消息/public static String check(Object cla, Class? extends Default groups) {if (cla ! null) {EnableArgumentsCheck enableArgumentsCheck cla.getClass().getAnnotation(EnableArgumentsCheck.class);if (enableArgumentsCheck null || !enableArgumentsCheck.enable()) {return StringUtils.EMPTY;}Field[] fields cla.getClass().getDeclaredFields();for (Field f : fields) {PropertiesVerify propertiesVerify f.getAnnotation(PropertiesVerify.class);if (propertiesVerify null) {continue;}f.setAccessible(true);Object value null;try {value getFieldValue(f.getName(), cla);} catch (Exception e) {throw new RuntimeException(String.format(获取字段%s值异常, f.getName()));}//分组判断if (isMatchGroups(groups, propertiesVerify)) {continue;}//判断是否为空if (value null propertiesVerify.isNotNull()) {return String.format(参数:%s不能为空, propertiesVerify.name());}if(Objects.isNull(value)){continue;}String res;if (value instanceof String) {//校验字符串参数res new StringArgumentsVerify((String) value, propertiesVerify, groups).check();} else if (value instanceof Long) {//检验Long类型参数res new LongArgumentsVerify(Long.parseLong(value.toString()), propertiesVerify, groups).check();} else if (value instanceof Integer) {//校验Integer类型参数res new IntegerArgumentsVerify(Integer.parseInt(value.toString()), propertiesVerify, groups).check();} else if (value instanceof Double) {//校验Double类型参数res new DoubleArgumentsVerify(formatDouble((Double) value), propertiesVerify, groups).check();} else if (value instanceof Date) {//校验Date类型参数res new DateArgumentsVerify((Date) value, propertiesVerify, groups).check();} else if (value instanceof List) {//list判断res new ListArgumentsVerify((ListObject) value, propertiesVerify, groups).check();} else if (value.getClass().isArray()) {//校验数组类型参数res new ListArgumentsVerify(Arrays.asList((Object[]) value), propertiesVerify, groups).check();} else {return check(value);}if (StringUtils.isNotBlank(res)) {return res;}}}return StringUtils.EMPTY;}private static String formatDouble(Double d) {NumberFormat nf NumberFormat.getInstance();//设置保留多少位小数nf.setMaximumFractionDigits(20);// 取消科学计数法nf.setGroupingUsed(false);//返回结果return nf.format(d);}private static boolean isMatchGroups(Class? extends Default groups, PropertiesVerify propertiesVerify) {if (groups ! null) {Class? extends Default[] fieldGroups propertiesVerify.groups();if (fieldGroups ! null) {boolean isMatchGroup false;for (Class c : fieldGroups) {if (c groups) {isMatchGroup true;break;}}if(!isMatchGroup){return true;}}}return false;}/** param fieldName 属性名称* param o 属性对象* return Object* throws IllegalAccessException* throws IllegalArgumentException* throws InvocationTargetException* throws NoSuchMethodException* throws SecurityException* Title: getFieldValue* Description: 获取对象属性的值* author ZENGCHONG/public static Object getFieldValue(String fieldName, Object o) throws Exception {String firstLetter fieldName.substring(0, 1).toUpperCase();String getter get firstLetter fieldName.substring(1);Method method o.getClass().getMethod(getter);Object value method.invoke(o);return value;} }7.实体类(用于测试) Data EnableArgumentsCheck() public class PrepareOrderRouteReq {/** */PropertiesVerify(name 下单编码, isNotNull true, minLength 1, maxLength 200)private String orderNumber;private String plateNumber;} 8.测试类 public class processTest {public static void main(String[] args) {PrepareOrderRouteReq req new PrepareOrderRouteReq();req.setOrderNumber({\n \t\actualWeight: 88.0,\n \t\addWorkday: 1.0,\n \t\autoDistributionFlag: 10,\n \t\billFlag: \20\,\n \t\contraband: 20,\n \t\createTime: 1725865110020,\n \t\customerServiceId: \12163\,\n \t\customerServiceName: \客服中台中心\,\n \t\deliveryAddWorkday: 0.0,\n \t\deliveryAging: 1726037880000,\n \t\freightAmount: 0.0,\n \t\goodsCategory: \,\n \t\goodsLabel: \40\,\n \t\goodsSize: \,\n \t\goodsType: \托寄物青0瓜\,\n \t\id: \155872956798825217\,\n \t\invalidFlag: 20,\n \t\linePlusAddDay: 0.0,\n \t\newCustomerFlag: 20,\n \t\nightOvertime: \10\,\n \t\orderTime: 1725865100000,\n \t\orderUploadMode: \20\,\n \t\pickupAddWorkday: 1.0,\n \t\pickupTime: \2024-09-09 14:58:00\,\n \t\predictWeight: 50.0,\n \t\receiveAddress: \上海市闵行区江川路690号上海电机学院(闵行校区)\,\n \t\receiveAreaCode: \10\,\n \t\receiveCustomerCode: \02106680981\,\n \t\receiveCustomerId: \8898771\,\n \t\receiveCustomerName: \上海每林\,\n \t\receiveMobile: \B2F64BDFB2A77B477C35867C00B7FDC5\,\n \t\receiveNodeId: \3997\,\n \t\receiveNodeName: \闵行点部\,\n \t\receivePhone: \0A967228DE1933E879C7F46FF845C8E8\,\n \t\receiveRegionCode: \021\,\n \t\reportNodeId: \5141\,\n \t\reportNodeName: \松岗新桥点部\,\n \t\requestFromAirport: \温州\,\n \t\requestToAirport: \上海虹桥\,\n \t\safetyCheck: \20\,\n \t\saleProjectCode: \XM-202204-0049\,\n \t\sendAddress: \广东省深圳市宝安区松岗街道松岗中心幼儿园2号1\,\n \t\sendAreaCode: \20\,\n \t\sendCustomerCode: \075508105755\,\n \t\sendCustomerId: \2207729\,\n \t\sendCustomerName: \深圳三四川科技\,\n \t\sendMobile: \C19C06D177CF75380C3754D5FABC24E8\,\n \t\sendNodeId: \5141\,\n \t\sendNodeName: \松岗新桥点部\,\n \t\sendRegionCode: \0755\,\n \t\serviceMode: \20\,\n \t\specialCode: \,\n \t\transferFlag: \20\,\n \t\updateTime: 1725865112166,\n \t\volumeWeight: 0.0,\n \t\waybillCount: 10,\n \t\waybillNo: \KY5000249115370\,\n \t\waybillRemark: \运单备注米123兰含电池\,\n \t\waybillSource: \240\,\n \t\waybillStatus: \70\,\n \t\waybillType: \2010\,\n \t\woodenFrameFlag: \\n });String check ArgumentsCheckUtil.check(req);System.out.println(check);} } 结果 使用到的jar包 dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.16.18/version/dependencydependencygroupIdjavax.validation/groupIdartifactIdvalidation-api/artifactIdversion2.0.1.Final/version/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion3.12.0/version/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-collections4/artifactIdversion4.4/version/dependency