/**
* 一个强大的 'form表单'-> 'Bean' 的参数封装器,支持对Bean对象内任意深度的递归封装。
* 以接收UserBasic有如下约定:
* 1,只针对继承了BaseObject的Model对象生效
* 2,基本类型属性直接按照属性名进行接收
* 3,对象类型属性的子属性按照 '{fieldName}.{childFieldName}' 形式接收
* 4,对象类型属性中的子对象属性的子属性按照 '{fieldName}.{childFieldName}.{childFieldName}',更深层次的子代对象以此类推
* 5,List对象类型属性按照 '{fieldName}.{index}.{childFieldName}' 其中{index}从0开始
* 6,属性的集合类型目前仅支持List,这基本足够了
*
* @author 汪浩淼 [et.tw@163.com]
* @since 14-6-3.
*/
public class SuperBeanResolver implements ParamResolver {
@Override
public boolean supports(ParamMetaData metaData) {
return metaData.getParamType().getSuperclass()!=null&&metaData.getParamType().getSuperclass().equals(BaseObject.class);
}
@Override
public Object resolve(Invocation inv, ParamMetaData metaData) throws Exception {
Class beanClass = metaData.getParamType();
return beanDeepResolve(inv,beanClass,null);
}
/**
* 深度遍历对象属性并封装信息
* @param inv
* @param beanClass
* @param parentPath
* @return
* @throws Exception
*/
public Object beanDeepResolve(Invocation inv,Class beanClass,String parentPath) throws Exception {
Object ins = beanClass.newInstance();
Field[] fields = beanClass.getDeclaredFields();
for (Field field:fields){
Method setter = ReflectUtil.getSetter(beanClass,field);
String currentFieldPath = StringUtils.isNoneBlank(parentPath)?parentPath+"."+field.getName():field.getName();
if (field.getType().equals(List.class)) {
List chiBeanList = new LinkedList();
Class chiClass = null;
ParameterizedType pt = (ParameterizedType) field.getGenericType();
Type[] types = pt.getActualTypeArguments();
if (types.length > 0) {
chiClass = (Class) types[0];
Field[] chiFields = chiClass.getDeclaredFields();
boolean goon = true;
int i = 0;
while (goon) {
boolean tmpflag = true;
Object chiIns = chiClass.newInstance();
for (Field chif : chiFields) {
String chiParamKey = new StringBuilder(currentFieldPath).append(".").append(i).append(".").append(chif).toString();
String chiParamValue = inv.getParameter(chiParamKey);
if (StringUtils.isNotBlank(chiParamValue)){
Method chiSetter = ReflectUtil.getSetter(chiClass,chif);
if (chiSetter!=null){
chiSetter.invoke(chiIns,ReflectUtil.cast(chiParamValue,chif.getType()));
}
tmpflag = false&tmpflag;
}else {
tmpflag = true&tmpflag;
}
}
goon = !tmpflag;
if (goon){
chiBeanList.add(chiIns);
}
i+=1;
}
if (chiBeanList.size()>0){
if (setter!=null){
setter.invoke(ins,chiBeanList);
}
}
}
}else if (field.getType().getSuperclass().equals(BaseObject.class)){
if (setter!=null){
setter.invoke(ins,beanDeepResolve(inv,field.getType(),currentFieldPath));
}
}else {
String paramVlaue = inv.getParameter(currentFieldPath);
if (StringUtils.isNoneBlank(paramVlaue)){
if (setter!=null){
setter.invoke(ins, ReflectUtil.cast(paramVlaue, field.getType()));
}
}
}
}
return ins;
}
}
/**
* 完成对表单中的数组对象的接收,数组对象的属性在表单中命名规则为:
* {num}.fieldName,其中num代表整个对象的索引,约定索引从0开始,并只针对
* 继承了BaseObject的model对象数组起作用。
*
* @author 汪浩淼 [et.tw@163.com]
* Date: 14-6-3.
*/
public class SuperArrayResolver implements ParamResolver {
@Override
public boolean supports(ParamMetaData metaData) {
Class paramType = metaData.getParamType();
return paramType.isArray()&¶mType.getComponentType()!=null&¶mType.getComponentType().getSuperclass().equals(BaseObject.class);
}
@Override
public Object resolve(Invocation inv, ParamMetaData metaData) throws Exception {
Class beanClazz = metaData.getParamType().getComponentType();
Field[] fields = beanClazz.getDeclaredFields();
List<Object> res = new LinkedList<Object>();
boolean goon = true;
int i =0;
while (goon){
boolean tmpflag = true;
Object ins = beanClazz.newInstance();
for(Field f:fields){
String paramKey = i+"."+f.getName();
String curvalue = inv.getParameter(paramKey);
if (StringUtils.isNotBlank(curvalue)){
tmpflag = false&tmpflag;
Method setter = ReflectUtil.getSetter(beanClazz,f);
if (setter!=null){
setter.invoke(ins,ReflectUtil.cast(curvalue,f.getType()));
}
}else {
tmpflag = true&tmpflag;
}
}
goon = !tmpflag;
if (goon){
res.add(ins);
}
i+=1;
}
Object realrs = Array.newInstance(beanClazz,res.size());
System.arraycopy(res.toArray(),0,realrs,0,res.size());
return realrs;
}
}
public class ReflectUtil {
/**
* 获取Bean的setter方法
* @param beanClazz
* @param field
* @return
*/
public static Method getSetter(Class beanClazz,Field field){
String fieldName = field.getName();
String methodKey = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
Method setter = null;
try {
setter = beanClazz.getDeclaredMethod(methodKey,field.getType());
} catch (NoSuchMethodException e) {
//
}
return setter;
}
/**
* 将请求参数转成对应的对象类型。
* @param ori
* @param type
* @return
*/
public static Object cast(String ori,Class type){
if (type.equals(int.class)||type.equals(Integer.class)){
return Integer.parseInt(ori);
}else if (type.equals(long.class)||type.equals(Long.class)){
return Long.parseLong(ori);
}else if (type.equals(String.class)){
return ori;
}else if (type.equals(boolean.class)||type.equals(Boolean.class)){
return Boolean.parseBoolean(ori);
}else if (type.equals(Date.class)){
try {
return DateUtils.parseDate(ori,"yyyy-MM-dd HH:mm:ss","yyyy/MM/dd HH:mm:ss","yyyyMMddHHmmss","yyyy-MM-dd","yyyy/MM/dd","yyyy-MM");
} catch (ParseException e) {
return null;
}
}
return null;
}
}