让JFinal的Controller的getModel方法支持不加前缀的变量名,方便extjs等使用

此实现需要修改JFinal源代码,目前该代码实现已经提交给JFinal了,估计下一个版本会添加该功能。想提前用的,自己修改代码重新编译jfinal吧。

修改 com.jfinal.core包下的ModelInjector.java 文件,(替换全部内容)

/**
 * Copyright (c) 2011-2015, James Zhan 詹波 ([email protected]).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jfinal.core;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.ActiveRecordException;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Table;
import com.jfinal.plugin.activerecord.TableMapping;

/**
 * ModelInjector
 */
final class ModelInjector {

	@SuppressWarnings("unchecked")
	public static <T> T inject(Class<?> modelClass, HttpServletRequest request, boolean skipConvertError) {
		String modelName = modelClass.getSimpleName();
		return (T)inject(modelClass, StrKit.firstCharToLowerCase(modelName), request, skipConvertError);
	}

	@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 RuntimeException(e);
		}

		if (model instanceof Model)
			injectActiveRecordModel((Model)model, modelName, request, skipConvertError);
		else
			injectCommonModel(model, modelName, request, modelClass, skipConvertError);

		return (T)model;
	}

	private static final void injectCommonModel(Object model, String modelName, HttpServletRequest request, Class<?> modelClass, boolean skipConvertError) {
		Method[] methods = modelClass.getMethods();
		//当modelName为null或者“”时,不添加前缀
		String modelNameAndDot = "";
		if(StrKit.notBlank(modelName)){
			modelNameAndDot= modelName + ".";
		}
		for (Method method : methods) {
			String methodName = method.getName();
			if (methodName.startsWith("set") == false)	// only setter method
				continue;

			Class<?>[] types = method.getParameterTypes();
			if (types.length != 1)						// only one parameter
				continue;

			String attrName = methodName.substring(3);
			String value = request.getParameter(modelNameAndDot + StrKit.firstCharToLowerCase(attrName));

			if (value != null) {
				try {
					method.invoke(model, TypeConverter.convert(types[0], value));
				} catch (Exception e) {
					if (skipConvertError == false)
					throw new RuntimeException(e);
				}
			}
		}
	}

	@SuppressWarnings("rawtypes")
	private static final void injectActiveRecordModel(Model<?> model, String modelName, HttpServletRequest request, boolean skipConvertError) {

		//当modelName为null或者“”时,不添加前缀
		String modelNameAndDot = "";
		if(StrKit.notBlank(modelName)){
			modelNameAndDot= modelName + ".";
		}
		Table table = TableMapping.me().getTable(model.getClass());
		Map<String, Class<?>> columnTypeMap = table.getColumnTypeMap();
		Map<String, String[]> parasMap = request.getParameterMap();
		//逐个遍历表字段
		for(Entry<String, Class<?>> entry: columnTypeMap.entrySet()){
			String key = modelNameAndDot + entry.getKey();
			//request中设定了相应的属性
			if(parasMap.containsKey(key)){
				Class colType = entry.getValue();
				String[] paraValue = parasMap.get(key);
				try {
					// Object value = Converter.convert(colType, paraValue != null ? paraValue[0] : null);
					Object value = paraValue[0] != null ? TypeConverter.convert(colType, paraValue[0]) : null;
					model.set(entry.getKey(), value);
				} catch (Exception ex) {
					if (skipConvertError == false)
						throw new RuntimeException("Can not convert parameter: " + key, ex);
				}
			}
		}
	}
}

如何使用:

getModel(Model.class,"")

第二个参数为空时,表示获取不加前缀的属性值,部位空时获取相应前缀的属性值。

假定User.class 有 username,password两个属性。

比如getModel(User.class,""),将获取username,password属性。

getModel(User.class,"user"),将获取user.username,user.password属性。

时间: 2024-10-06 08:22:00

让JFinal的Controller的getModel方法支持不加前缀的变量名,方便extjs等使用的相关文章

对Objective-C相关的类、方法、属性、成员变量介绍

类的定义@interface FirstClass :NSObject@end//@interface表示声明的是一个类,“:”表示继承关系,@end类的结束类的实现@implementation FirstClass方法的声明+(void)print;-(id)init;//"+"表示声明的是一个类方法,由雷鸣调用//“-”表示声明的时实例方法,必须由类的对象来调用//不带参数的方法在调用时,会使用隐藏的self参数来访问实例变量的属性.声明带参数的方法:+(void)initWit

Objective-C——类、方法、属性、成员变量

有过相关编程语言基础,了解C++/java的相信对类的类.对象等概念是了解的.在此我也不做过多地赘述. 关于OC中类的定义及方法使用这块,OC定义了一套自己的规范 类的定义: @interface FirstClass :NSObject @end //@interface表示声明的是一个类,":"表示继承关系,@end类的结束 类的实现 @implementation FirstClass 方法的声明: +(void)print; -(id)init; //"+"

Spring Boot如何让某个Controller支持跨源请求,以及如何让Controller类某个成员方法支持跨源请求

在前面我们已经讨论了Spring Boot 如何全局支持跨源请求.如果你想了解可以查看这篇文章 下面我们讨论另一种场景.有些时候,你需要让你的应用在大部分的时候,仅仅支持当前域名下的请求.而仅仅在极其特殊的几个场合下,才支持跨源请求.这个时候,你需要把跨源请求仅仅缩小在几个Controller上,或者Controller类的几个成员方法上.这个时候你需要用到如下的注解:@CrossOrigin(origins = "*", maxAge = 3600) .把这个注解放到 Control

拦截器getmodel方法什么时候被调用(没搞懂有什么鸟用,自己搭的项目中用到了这个)

拦截器是Struts2最强大的特性之一,它是一种可以让用户在Action执行之前和Result执行之后进行一些功能处理的机制.Struts2 的预定义拦截器 modelDriven 如果action实现了ModelDriven接口,它将getModel方法取得的模型对象存入OgnlValueStack中.

iframe子页面调用父页面javascript函数的方法(支持chrome和IE的通用方法)

iframe子页面调用父页面javascript函数的方法 今天遇到一个iframe子页面调用父页面js函数的需求,解决起来很简单,但是在chrome浏览器遇到一点小问题.顺便写一下iframe的父页面调用子页面javascript函数的方法吧,备用! 1.iframe子页面调用 父页面js函数 子页面调用父页面函数只需要写上window.praent就可以了.比如调用a()函数,就写成: window.praent.a(); 但是我在chrome浏览器下却发现此方法无效了!查了半天才了解,在c

datasnap远程方法支持自定义对象传参

有同仁需要远程方法传输自定义的数据类型,他以为要自己写代码会很复杂,其实DATASNAP早就为我们想到了. datasnap的数据序列和还原真是无与伦比的强大,其远程方法支持自定义对象传参,DATASNAP会自动使用JSON序列和还原自定义的对象. 1)自定义一个对象 type TMyInfo = class(TObject) public AccountNo: string; SQL: string; Params: string; RecsMax: Integer; end; 2)服务端远程

ASP.NET MVC4在View中调用当前Controller中的方法

调用当前Controller中的方法 1 @{ 2 ((HomeController)ViewContext.Controller).Method1(); 3 } 调用静态方法 1 @{ 2 SomeClass.Method(); 3 }

Spring4.0MVC学习资料,Controller中的方法详解和使用(四)

在以前,mvc的框架,基本上就是struts框架了.但是现在不一样了.springmvc出来了.spring的mvc框架不亚于struts了,springmvc出来了,我们有了更多的选择. Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还可以是 Struts 这样的 We

Spring的Aspect切面类不能拦截Controller中的方法

根本原因在于<aop:aspectj-autoproxy />这句话是在spring的配置文件内,还是在springmvc的配置文件内.如果是在spring的配置文件内,则@Controller中的方法不会被拦截. 看一下applicationContext.xml中bean扫描的配置,此处排除了controller层的扫描: <context:component-scan base-package="com"> <context:exclude-filt