反射可以根据class对象获取bean的属性和方法以及等等,解析json字符串后,创建对象,并给对象属性赋值,这些只要属性命名和赋值逻辑对应很容易实现,现在要说的是,配合自定义注解,使用可以更加灵活,
这是一位大神写的,给了我不少启示
先定义属性注解 import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.TYPE}) public @interface ApiField { String[] value() default ""; }
bean的对象,上面加载注解,可以使命名更加灵活,
import com.jwebplat.util.bean.ApiField; @ApiField(value = { "data", "pageList" }) public class TaobaoItemInfo { @ApiField("auctionId") private Long auctionId; @ApiField("title") private String title; @ApiField("auctionUrl") private String auctionUrl; @ApiField("sellerId") private Long sellerId; @ApiField("userType") private Integer userType; @ApiField("nick") private String nick; @ApiField("tkCommonFee") private Double tkCommFee; @ApiField("tkCommonRate") private Double tkRate; @ApiField("biz30day") private Integer biz30day; @ApiField("zkPrice") private Double zkPrice; @ApiField("couponInfo") private String couponInfo; @ApiField("couponTotalCount") private Integer couponTotalCount; @ApiField("couponLeftCount") private Integer couponLeftCount; @ApiField("couponAmount") private Double couponAmount; @ApiField("couponStartFee") private Double couponStartFee; @ApiField("pictUrl") private String pictUrl; public Long getAuctionId() { return auctionId; } public void setAuctionId(Long auctionId) { this.auctionId = auctionId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuctionUrl() { return auctionUrl; } public void setAuctionUrl(String auctionUrl) { this.auctionUrl = auctionUrl; } public Long getSellerId() { return sellerId; } public void setSellerId(Long sellerId) { this.sellerId = sellerId; } public Integer getUserType() { return userType; } public void setUserType(Integer userType) { this.userType = userType; } public String getNick() { return nick; } public void setNick(String nick) { this.nick = nick; } public Double getTkCommFee() { return tkCommFee; } public void setTkCommFee(Double tkCommFee) { this.tkCommFee = tkCommFee; } public Double getTkRate() { return tkRate; } public void setTkRate(Double tkRate) { this.tkRate = tkRate; } public Integer getBiz30day() { return biz30day; } public void setBiz30day(Integer biz30day) { this.biz30day = biz30day; } public Double getZkPrice() { return zkPrice; } public void setZkPrice(Double zkPrice) { this.zkPrice = zkPrice; } public String getCouponInfo() { return couponInfo; } public void setCouponInfo(String couponInfo) { this.couponInfo = couponInfo; } public Integer getCouponTotalCount() { return couponTotalCount; } public void setCouponTotalCount(Integer couponTotalCount) { this.couponTotalCount = couponTotalCount; } public Integer getCouponLeftCount() { return couponLeftCount; } public void setCouponLeftCount(Integer couponLeftCount) { this.couponLeftCount = couponLeftCount; } public Double getCouponAmount() { return couponAmount; } public void setCouponAmount(Double couponAmount) { this.couponAmount = couponAmount; } public Double getCouponStartFee() { return couponStartFee; } public void setCouponStartFee(Double couponStartFee) { this.couponStartFee = couponStartFee; } public String getPictUrl() { return pictUrl; } public void setPictUrl(String pictUrl) { this.pictUrl = pictUrl; } }
接下来将json字符串转成JsonObject,通过扫描属性的上面的注解,进行赋值,这样即使json字符串里的名字和属性的命令不一致也可以照样赋值,这里给我个人的启发是,属性注解可以如此使用,那么方法上也可以加注解,而且由此我想到了,那些框架的注解原理亦是如此,感觉反射和自定义注解妙用无穷,这里我就不贴自己的代码了
public static <T> T toBean(JsonObject jsonObject, Class<T> cla) throws IntrospectionException, ReflectiveOperationException, IllegalArgumentException { if(jsonObject == null || jsonObject.isJsonNull()) { return null; } T t = cla.newInstance(); Field[] fields = cla.getDeclaredFields(); for (Field field : fields) { String fieldName = field.getName(); JsonElement je = getValueByPath(jsonObject, fieldName); if (je != null && !je.isJsonNull()) { PropertyDescriptor pd = new PropertyDescriptor(fieldName, cla); Method method = pd.getWriteMethod(); if (method != null) { Class<?> fieldType = field.getType(); if (isPrimitive(fieldType)) { // 如果是基本类型或是其封装类型 method.invoke(t, toPrimitive(je, fieldType)); } else if (fieldType.isEnum()) { // 如果是枚举类型 } else if (fieldType.isArray()) { // 如果是数组 } else if (Collection.class.isAssignableFrom(fieldType) && je.isJsonArray()) { // 如果是Collection数组 ParameterizedType type = (ParameterizedType) field.getGenericType(); method.invoke(t, toCollection(je.getAsJsonArray(), (Class<?>) type.getActualTypeArguments()[0])); } else if (fieldType.isInterface() || fieldType.isAnnotation() || fieldType.isAnonymousClass() || fieldType.isMemberClass() || fieldType.isLocalClass()) { // 如果是 接口 或者是 注解 或者是 匿名类 或者是成员类 局部类 } else if (je.isJsonObject()) { method.invoke(t, toBean(je.getAsJsonObject(), fieldType)); } } } } return t; }