JFinal 源码导读第六天(1) Validator分析

1.源码讨论
@Before(BlogValidator.class)
	public void save() {
		getModel(Blog.class).save();
		redirect("/blog");
	}
2.@Before(BlogValidator.class)
这段代码是在方法执行前会调用BlogValidator拦截器
public class BlogValidator extends Validator {
	
	protected void validate(Controller controller) {
		validateRequiredString("blog.title", "titleMsg", "请输入Blog标题!");
		validateRequiredString("blog.content", "contentMsg", "请输入Blog内容!");
	}
	
	protected void handleError(Controller controller) {
		controller.keepModel(Blog.class);
		
		String actionKey = getActionKey();
		if (actionKey.equals("/blog/save"))
			controller.render("add.html");
		else if (actionKey.equals("/blog/update"))
			controller.render("edit.html");
	}
}
3.会调用Validator中的intercept方法
Validator validator = null;
		try {validator = getClass().newInstance();}
		catch (Exception e) {throw new RuntimeException(e);}
		
		validator.controller = invocation.getController();
		validator.invocation = invocation;
		
		try {validator.validate(validator.controller);} 
		catch (ValidateException e) {/* should not be throw */}			// short circuit validate need this
		
		if (validator.invalid)
			validator.handleError(validator.controller);
		else
			invocation.invoke();
4. validator.validate(validator.controller)这段代码是关键
validateRequiredString("blog.title", "titleMsg", "请输入Blog标题!");
validateRequiredString("blog.content", "contentMsg", "请输入Blog内容!");
5.validateRequiredString,这个代码非常简单就是request获取参数值,如果为空,放到request中去
/**
	 * Validate required string.
	 */
	protected void validateRequiredString(String field, String errorKey, String errorMessage) {
		String value = controller.getPara(field);
		if (value == null || "".equals(value.trim()))
			addError(errorKey, errorMessage);
	}
6.当我们这个字段保存填为空的时候,我们就会执行如下代码啦
	protected void handleError(Controller controller) {
		controller.keepModel(Blog.class);
		
		String actionKey = getActionKey();
		if (actionKey.equals("/blog/save"))
			controller.render("add.html");
		else if (actionKey.equals("/blog/update"))
			controller.render("edit.html");
	}
7.controller.keepModel(Blog.class); 
	public Controller keepModel(Class modelClass) {
		String modelName = StringKit.firstCharToLowerCase(modelClass.getSimpleName());
		keepModel(modelClass, modelName);
		return this;
	}
8.StringKit.firstCharToLowerCase(modelClass.getSimpleName())  其实就是首字母小写
9.keepModel(modelClass, modelName);这行代码很简单啦
	public Controller keepModel(Class modelClass, String modelName) {
		Object model = ModelInjector.inject(modelClass, modelName, request, true);
		request.setAttribute(modelName, model);
		return this;
	}
10.Object model = ModelInjector.inject(modelClass, modelName, request, true); 这段代码就是运用反射给变量注入值
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static final <T> T inject(Class<?> modelClass, String modelName, HttpServletRequest request, boolean skipConvertError) {
		Object model = null;
		try {
			model = modelClass.newInstance();
		} catch (Exception e) {
			throw new ModelInjectException(e);
		}
		
		if (model instanceof Model)
			injectActiveRecordModel((Model)model, modelName, request, skipConvertError);
		else
			injectCommonModel(model, modelName, request, modelClass, skipConvertError);
		
		return (T)model;
	}
11.上面的代码会执行下面这个方法的代码,下面代码的核心意义就根据数据库表的字段和类型将值放入到Model的Map中
@SuppressWarnings("rawtypes")
	private static final void injectActiveRecordModel(Model<?> model, String modelName, HttpServletRequest request, boolean skipConvertError) {
		TableInfo tableInfo = TableInfoMapping.me().getTableInfo(model.getClass());
		
		String modelNameAndDot = modelName + ".";
		
		Map<String, String[]> parasMap = request.getParameterMap();
		for (Entry<String, String[]> e : parasMap.entrySet()) {
			String paraKey = e.getKey();
			if (paraKey.startsWith(modelNameAndDot)) {
				String paraName = paraKey.substring(modelNameAndDot.length());
				Class colType = tableInfo.getColType(paraName);
				if (colType == null)
					throw new ActiveRecordException("The model attribute " + paraKey + " is not exists.");
				String[] paraValue = e.getValue();
				try {
					// Object value = Converter.convert(colType, paraValue != null ? paraValue[0] : null);
					Object value = paraValue[0] != null ? TypeConverter.convert(colType, paraValue[0]) : null;
					model.set(paraName, value);
				} catch (Exception ex) {
					if (skipConvertError == false)
						throw new ModelInjectException("Can not convert parameter: " + modelNameAndDot + paraName, ex);
				}
			}
		}
	}



你可能感兴趣的:(Validator,jFinal)