
org.swiftboot.web.result.BasePopulateResult Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swiftboot-web Show documentation
Show all versions of swiftboot-web Show documentation
Basic module for enterprise web applications
package org.swiftboot.web.result; import com.fasterxml.jackson.annotation.JsonIgnore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.swiftboot.data.model.entity.BaseEntity; import org.swiftboot.data.model.entity.IdPersistable; import org.swiftboot.util.BeanUtils; import org.swiftboot.web.Info; import org.swiftboot.web.R; import org.swiftboot.web.annotation.PopulateIgnore; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.*; /** * 提供将入实体类的属性值填入返回值的方法。如果 Result 存在的属性名称在实体类中不存在的话,则抛出异常。 *
@OneToMany 的属性填充到 Result 实例中,前提是 Result 实例中对应的属性类型必须也是继承自 BasePopulateResult 的类。 * 注意:一对一关系如果需要填充,则必须使用 fetch = FetchType.LAZY 来标注,否则将无法通过反射获取到带有属性值的子类。 * 标记 {@link JsonIgnore} 注解的 Result 类属性不会被处理。 * 如果希望某个实体类中不存在的属性也能出现在 Result 类中,那么可以用 {@link PopulateIgnore} 来标注这个属性。 * * @author swiftech **/ public abstract class BasePopulateResultpopulateByEntity(E entity)
方法将实体类的属性填充到当前对象实例中。 * 静态方法populateByEntity(E entity, BasePopulateResult
将指定实体类属性值填充至指定的 Result 实例中。 * 填充方法支持将实体类的result) @OneToOne
和implements Result { /** * 按照返回值类型创建返回值对象,并从实体类填充返回值 * * @param resultClass 返回对象类型 * @param entity 实体类 * @param * @return */ public static T createResult( Class resultClass, IdPersistable entity) { if (resultClass == null || entity == null) { throw new IllegalArgumentException(Info.get(BasePopulateResult.class, R.REQUIRE_PARAMS)); } T ret; Constructor constructor; try { constructor = resultClass.getConstructor(); } catch (NoSuchMethodException e) { e.printStackTrace(); throw new RuntimeException(Info.get(BasePopulateResult.class, R.REQUIRE_NO_PARAM_CONSTRUCTOR1, resultClass.getName())); } try { ret = constructor.newInstance(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(Info.get(BasePopulateResult.class, R.CONSTRUCT_FAIL2, resultClass.getName(), BasePopulateResult.class)); } ret.populateByEntity(entity); return ret; } /** * 从实体类填充当前返回值对象,如果属性值是其他对象的集合,那么也会自动从实体类中获取对应名字的集合来填充返回值的集合 * * @param entity * @return */ public BasePopulateResult populateByEntity(E entity) { return BasePopulateResult.populateByEntity(entity, this); } /** * 从实体类填充属性至返回值对象,如果属性值是其他对象的集合,那么也会自动从实体类中获取对应名字的集合来填充返回值的集合 * * @param entity * @param result * @return */ public static BasePopulateResult populateByEntity(E entity, BasePopulateResult result) { if (entity == null) { throw new RuntimeException(Info.get(BasePopulateResult.class, R.REQUIRE_ENTITY)); } Logger log = LoggerFactory.getLogger(BasePopulateResult.class); log.trace(Info.get(BasePopulateResult.class, R.POPULATE_FROM_ENTITY1, entity)); /* * 先处理一对多关联(保证ID属性先被处理,后续处理时略过这些字段) */ List ignoredFieldNameList = new LinkedList<>();// 需要忽略的目标属性名称 List fieldsByType = BeanUtils.getDeclaredFieldsByType(entity, BaseEntity.class); for (Field srcField : fieldsByType) { String relationFiledNameInResultClass = srcField.getName() + "Id"; try { Field targetField = result.getClass().getDeclaredField(relationFiledNameInResultClass); if (targetField.getAnnotation(JsonIgnore.class) != null || targetField.getAnnotation(PopulateIgnore.class) != null) { continue; } BaseEntity parentEntity = (BaseEntity) BeanUtils.forceGetProperty(entity, srcField); if (parentEntity != null) { BeanUtils.forceSetProperty(result, relationFiledNameInResultClass, parentEntity.getId()); ignoredFieldNameList.add(relationFiledNameInResultClass); // 记录目标属性名称 } } catch (Exception e) { // 忽略处理 continue; } } /* * 处理(一对一)关联的 Result 对象 */ List fieldsOne2One = BeanUtils.getDeclaredFieldsByTypeIgnore(result, BasePopulateResult.class, JsonIgnore.class, PopulateIgnore.class); for (Field targetField : fieldsOne2One) { ignoredFieldNameList.add(targetField.getName()); Field srcField; try { srcField = BeanUtils.getDeclaredField(entity, targetField.getName()); } catch (NoSuchFieldException e) { e.printStackTrace(); throw new RuntimeException(Info.get(R.class, R.FIELD_REQUIRED_FOR_ENTITY2, entity.getClass(), targetField.getName())); } // String getterNameInEntity = "get" + Character.toUpperCase(srcField.getName().charAt(0)) + srcField.getName().substring(1); // Object subEntity = null; // try { // subEntity = BeanUtils.forceInvokeMethod(entity, getterNameInEntity); // } catch (NoSuchMethodException e) { // e.printStackTrace(); // throw new RuntimeException(String.format("实体类 %s 缺少参数必要的属性的 Getter: %s", entity.getClass(), targetField.getName())); // } Object subEntity = BeanUtils.forceGetProperty(entity, srcField); if (subEntity instanceof IdPersistable) { Class subResultClass = (Class) targetField.getGenericType(); if (subResultClass != null) { BasePopulateResult subResult = createResult(subResultClass, (IdPersistable) subEntity); BeanUtils.forceSetProperty(result, targetField, subResult); } } } /* * 接着处理所有除外键属性之外的所有可用属性 */ Collection targetFields = BeanUtils.getFieldsIgnore(result.getClass(), JsonIgnore.class, PopulateIgnore.class); for (Field targetField : targetFields) { if (ignoredFieldNameList.contains(targetField.getName())) { continue; } Field srcField; try { srcField = BeanUtils.getDeclaredField(entity, targetField.getName()); } catch (NoSuchFieldException e) { e.printStackTrace(); throw new RuntimeException(Info.get(R.class, R.FIELD_REQUIRED_FOR_ENTITY2, entity.getClass(), targetField.getName())); } // unlock boolean accessible = targetField.isAccessible(); targetField.setAccessible(true); // 处理集合类属性 if (Collection.class.isAssignableFrom(srcField.getType()) && Collection.class.isAssignableFrom(targetField.getType())) { try { Type[] actualTypeArguments = ((ParameterizedType) targetField.getGenericType()).getActualTypeArguments(); if (actualTypeArguments.length > 0) { Collection srcCollection = (Collection) BeanUtils.forceGetProperty(entity, srcField.getName()); if (srcCollection != null && !srcCollection.isEmpty()) { Collection targetCollection = (Collection) BeanUtils.forceGetProperty(result, targetField.getName()); Class elementClass = (Class) actualTypeArguments[0]; if (targetCollection == null) { if (Set.class.isAssignableFrom(targetField.getType())) { // 如果集合为 TreeSet 并且其中的元素的类型实现了 Comparable 接口,那么返回 TreeSet if (TreeSet.class.isAssignableFrom(targetField.getType()) && Comparable.class.isAssignableFrom((Class>) elementClass)) { targetCollection = new TreeSet<>(); } else { targetCollection = new HashSet<>(); } } else if (List.class.isAssignableFrom(targetField.getType())) { targetCollection = new LinkedList<>(); } targetField.set(result, targetCollection); } for (Object subEntity : srcCollection) { if (subEntity instanceof IdPersistable) { BasePopulateResult subResult = createResult(elementClass, (IdPersistable) subEntity); targetCollection.add(subResult); } } } } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(Info.get(BasePopulateResult.class, R.POPULATE_COLLECTION_FAIL1, srcField.getName())); } } else { try { Object value = BeanUtils.forceGetProperty(entity, srcField.getName()); targetField.set(result, value); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(Info.get(R.class, R.POPULATE_FIELD_FAIL1, srcField.getName())); } } targetField.setAccessible(accessible); } return result; } }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy