论坛首页 Java企业应用论坛

java简单校验器,持续扩展

浏览 2717 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-05-23   最后修改:2012-06-15
package demo.validate;

import java.util.ArrayList;
import java.util.List;

public class Validation {

	public static void main(String[] args) {
		String msg = null;
		// validate one text
		msg = Validation.newInstance().addText("123456").addRule(
				RuleType.NOT_EMPTY).addRule(RuleType.LENGTH, 3).addRule(
				RuleType.NUMBER, 0, 123458).addRule(RuleType.NUMERIC_STRING,
				"123450", "123490").addRule(new Rule() {

			@Override
			public String validate(String text) {
				// validate if the number is odd
				if (Integer.parseInt(text) % 2 == 0) {
					return String.format("%s is not an odd number", text);
				}
				return null;
			}
		}).validate();
		System.out.println(msg);

		// validate batch text by same rule
		Validation instance = Validation.newInstance().addRule(
				RuleType.NOT_EMPTY).addRule(RuleType.LENGTH, 3).addRule(
				RuleType.NUMBER, 0, 123458);
		String[] batch = new String[10];
		for (int i = 0; i < batch.length; i++) {
			batch[i] = "12345" + i;
		}
		for (int i = 0; i < batch.length; i++) {
			String result = instance.addText(batch[i]).validate();
			System.out.println(String.format("text:%s,validate result:%s",
					batch[i], result));
		}
	}

	private static final String NUMBER_REGEX = "([1-9]\\d*)|(0)";
	private static final String NUMERIC_STRING_REGEX = "\\d+";

	public enum RuleType {
		NOT_EMPTY, LENGTH, NUMERIC_STRING, NUMBER, REGEX
	}

	public interface Rule {
		String validate(String text);
	}

	private String text;
	private List<Rule> items = new ArrayList<Rule>();

	private Validation() {

	}

	public static Validation newInstance() {
		return new Validation();
	}

	public Validation addText(String text) {
		return addText(text, true);
	}

	public Validation addText(String text, boolean trim) {
		this.text = text;
		if (trim) {
			if (this.text != null) {
				this.text.trim();
			}
		}
		return this;
	}

	public Validation addRule(Rule rule) {
		items.add(rule);
		return this;
	}

	public Validation addRule(RuleType rule) {
		items.add(new CommonRule(rule));
		return this;
	}

	public Validation addRule(RuleType rule, Object... params) {
		items.add(new CommonRule(rule, params));
		return this;
	}

	public String validate() {
		return Validation.validate(this.text, this.items);
	}

	private class CommonRule implements Rule {
		private RuleType rule;
		private Object[] params = null;

		private CommonRule() {

		}

		private CommonRule(RuleType rule) {
			this.rule = rule;
		}

		private CommonRule(RuleType rule, Object... params) {
			this.rule = rule;
			this.params = params;
		}

		public RuleType getRule() {
			return rule;
		}

		public Object[] getParams() {
			return params;
		}

		@Override
		public String validate(String text) {
			return Validation.validate(text, this);
		}
	}

	public static String validate(String text, List<Rule> rules) {
		Rule[] items = null;
		if (rules != null && !rules.isEmpty()) {
			items = rules.toArray(new Rule[rules.size()]);
		}
		return validate(text, items);
	}

	public static String validate(String text, Rule[] rules) {
		if (rules == null) {
			return null;
		}
		String res = null;
		for (int i = 0; i < rules.length; i++) {
			Rule validator = rules[i];
			if (validator == null) {
				continue;
			}
			res = validator.validate(text);
			if (res != null) {
				break;
			}
		}
		return res;
	}

	private static String validate(String text, CommonRule rule) {
		String res = null;
		RuleType ruleType = rule.getRule();
		Object[] params = rule.getParams();
		if (ruleType == RuleType.NOT_EMPTY) {
			if ((res = validateEmpty(text)) != null) {
				return res;
			}
		}
		if (ruleType == RuleType.LENGTH) {
			int min = 0;
			int max = 0;
			if (params != null) {
				if (params.length > 0) {
					min = (Integer) params[0];
					if (params.length > 1) {
						max = (Integer) params[1];
					}
				}
			}
			if ((res = validateLength(text, min, max)) != null) {
				return res;
			}
		}
		if (ruleType == RuleType.NUMERIC_STRING) {
			String min = null;
			String max = null;
			if (params != null) {
				if (params.length > 0) {
					min = (String) params[0];
					if (params.length > 1) {
						max = (String) params[1];
					}
				}
			}
			if ((res = validateNumericString(text, min, max)) != null) {
				return res;
			}
		}
		if (ruleType == RuleType.NUMBER) {
			int min = 0;
			int max = 0;
			if (params != null) {
				if (params.length > 0) {
					min = (Integer) params[0];
					if (params.length > 1) {
						max = (Integer) params[1];
					}
				}
			}
			if ((res = validateNumber(text, min, max)) != null) {
				return res;
			}
		}
		if (ruleType == RuleType.REGEX) {
			if ((res = validateRegex(text, (String) params[0])) != null) {
				return res;
			}
		}
		return null;
	}

	public static String validateEmpty(String text) {
		if (text == null || text.isEmpty()) {
			return text + " is empty";
		}
		return null;
	}

	public static String validateNumericString(String text, String min,
			String max) {
		if (!text.matches(NUMERIC_STRING_REGEX)) {
			return text + " is not a numeric string";
		}
		String msg = "";
		if (min != null) {
			msg = " more than " + min;
		}
		if (max != null) {
			msg += (msg.length() == 0 ? "" : " and ") + " less than " + max;
		}
		msg = text + " is invalid, should be" + msg;
		if (min != null && text.compareTo(min) < 0) {
			return msg;
		}
		if (max != null && text.compareTo(max) > 0) {
			return msg;
		}
		return null;
	}

	public static String validateNumber(String text, int min, int max) {
		if (!text.matches(NUMBER_REGEX)) {
			return text + " is not a number";
		}
		int number = Integer.parseInt(text);
		String msg = "";
		if (min > 0) {
			msg = " more than " + min;
		}
		if (max > 0) {
			msg += (msg.length() == 0 ? "" : " and ") + " less than " + max;
		}
		if (msg.length() == 0) {
			return null;
		}
		msg = text + " is invalid, should be" + msg;
		if (min > 0 && number < min) {
			return msg;
		}
		if (max > 0 && number > max) {
			return msg;
		}
		return null;
	}

	public static String validateLength(String text, int minLength,
			int maxLength) {
		int length = text.length();
		String msg = "";
		if (minLength > 0) {
			msg = " more than " + minLength;
		}
		if (maxLength > 0) {
			msg += (msg.length() == 0 ? "" : " and ") + " less than "
					+ maxLength;
		}
		if (msg.length() == 0) {
			return null;
		}
		msg = text + " is invalid, the length should be" + msg;
		if (minLength > 0 && length < minLength) {
			return msg;
		}
		if (maxLength > 0 && length > maxLength) {
			return msg;
		}
		return null;
	}

	public static String validateRegex(String text, String regex) {
		if (text.matches(regex)) {
			return null;
		}
		return text + " is invalid";
	}

	public static String validate(String text, Rule validator) {
		if (validator == null) {
			return null;
		}
		return validator.validate(text);
	}

}

123456 is not an odd number
text:123450,validate result:null
text:123451,validate result:null
text:123452,validate result:null
text:123453,validate result:null
text:123454,validate result:null
text:123455,validate result:null
text:123456,validate result:null
text:123457,validate result:null
text:123458,validate result:null
text:123459,validate result:123459 is invalid, should be less than 123458
   发表时间:2012-05-23   最后修改:2012-05-23
楼主,你稍微写点注释嘛,都不知道你要干什么。
我承认你那个链式操作也算是最近流行的语法糖了。顶一个
0 请登录后投票
   发表时间:2012-06-13   最后修改:2012-06-13
这次又重构了一下,好看一点了
其实写这个主要是有些时候,不需要引入第三方的框架,比如小的java 程序,
或者linux 命令行调个简单的java程序,还是自己写好,不过python用在linux 命令行要更好
有些时候shell功能确实不够强大啊
0 请登录后投票
   发表时间:2012-06-14  
把类名,方法名更改了一下,这次总算觉得不那么别扭了
0 请登录后投票
   发表时间:2012-06-14   最后修改:2012-06-15
又接着改了一下,主要是默认addText 是trim的,如果需要保留原字符串不trim,使用第2个重载方法

之前的改动为,
修改enum 类名 Rule -> RuleType
修改Validator接口 Validator -> Rule
修改ValidationItem ValidationItem -> CommonRule
修改了函数中的变量名, eclipse的批量修改变量的方法很好用
增加numeric string类型的校验,区别整数和数字字符串
增加Rule接口,提供扩展入口,可以添加新的Rule
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics