反射加自定义注解使用场景--Json字符串解析成bean

反射可以根据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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值