如何防止对象在 Retrofit2 的 API 调用中发送空字段

Posted

技术标签:

【中文标题】如何防止对象在 Retrofit2 的 API 调用中发送空字段【英文标题】:How to prevent object to send null fields on API call for Retrofit2 【发布时间】:2017-08-01 18:43:25 【问题描述】:

我面临改造对象字段的问题。 例如:我有对象名称 criteria,它有 20 个字段 不,我只想在 API 调用时发送前 4 个字段,其余的都应该是api调用时忽略。

下面是我的对象:

public class Criteria 

@SerializedName("mlsp_id")
@Expose
private String mlspId;
@SerializedName("listing_key")
@Expose
private String listing_key;
@SerializedName("limit")
@Expose
private String limit;
@SerializedName("add_to_log")
@Expose
private Integer addToLog;
@SerializedName("location")
@Expose
private String location;
@SerializedName("property_type")
@Expose
private List<String> propertyType = null;
@SerializedName("price")
@Expose
private Price price;
@SerializedName("beds")
@Expose
private Beds beds;
@SerializedName("baths")
@Expose
private Baths baths;
@SerializedName("floor_area")
@Expose
private FloorArea floorArea;
@SerializedName("lot_size")
@Expose
private LotSize lotSize;
@SerializedName("year_built")
@Expose
private YearBuilt yearBuilt;
@SerializedName("maintenance_fee")
@Expose
private MaintenanceFee maintenanceFee;
@SerializedName("dom")
@Expose
private String dom;
@SerializedName("keywords")
@Expose
private String keywords;
@SerializedName("exclude")
@Expose
private List<String> exclude = null;
@SerializedName("show_with")
@Expose
private List<String> showWith = null;
@SerializedName("map_boundary")
@Expose
private List<String> mapBoundary = null;
@SerializedName("sort_by")
@Expose
private String sortBy;
@SerializedName("sch_level")
@Expose
private String schLevel;
@SerializedName("sch_type")
@Expose
private String schType;
@SerializedName("sch_rating")
@Expose
private Integer schRating;
@SerializedName("listing_within_sch_radius")
@Expose
private Integer listingWithinSchRadius;
@SerializedName("sch_id")
@Expose
private String schId;
@SerializedName("sch_within_radius")
@Expose
private String schWithinRadius;
@SerializedName("listing_within_skytrain_station_radius")
@Expose
private Integer listingWithinSkytrainStationRadius;
@SerializedName("listing_within_skytrain_station_transit_minute")
@Expose
private Integer listingWithinSkytrainStationTransitMinute;
@SerializedName("skytrain_station_id")
@Expose
private Integer skytrainStationId;
@SerializedName("skytrain_station_within_radius")
@Expose
private Integer skytrainStationWithinRadius;

public String getListing_key() 
    return listing_key;


public void setListing_key(String listing_key) 
    this.listing_key = listing_key;


public String getLimit() 
    return limit;


public void setLimit(String limit) 
    this.limit = limit;


public String getMlspId() 
    return mlspId;


public void setMlspId(String mlspId) 
    this.mlspId = mlspId;


public Integer getAddToLog() 
    return addToLog;


public void setAddToLog(Integer addToLog) 
    this.addToLog = addToLog;


public String getLocation() 
    return location;


public void setLocation(String location) 
    this.location = location;


public List<String> getPropertyType() 
    return propertyType;


public void setPropertyType(List<String> propertyType) 
    this.propertyType = propertyType;


public Price getPrice() 
    return price;


public void setPrice(Price price) 
    this.price = price;


public Beds getBeds() 
    return beds;


public void setBeds(Beds beds) 
    this.beds = beds;


public Baths getBaths() 
    return baths;


public void setBaths(Baths baths) 
    this.baths = baths;


public FloorArea getFloorArea() 
    return floorArea;


public void setFloorArea(FloorArea floorArea) 
    this.floorArea = floorArea;


public LotSize getLotSize() 
    return lotSize;


public void setLotSize(LotSize lotSize) 
    this.lotSize = lotSize;


public YearBuilt getYearBuilt() 
    return yearBuilt;


public void setYearBuilt(YearBuilt yearBuilt) 
    this.yearBuilt = yearBuilt;


public MaintenanceFee getMaintenanceFee() 
    return maintenanceFee;


public void setMaintenanceFee(MaintenanceFee maintenanceFee) 
    this.maintenanceFee = maintenanceFee;


public String getDom() 
    return dom;


public void setDom(String dom) 
    this.dom = dom;


public String getKeywords() 
    return keywords;


public void setKeywords(String keywords) 
    this.keywords = keywords;


public List<String> getExclude() 
    return exclude;


public void setExclude(List<String> exclude) 
    this.exclude = exclude;


public List<String> getShowWith() 
    return showWith;


public void setShowWith(List<String> showWith) 
    this.showWith = showWith;


public List<String> getMapBoundary() 
    return mapBoundary;


public void setMapBoundary(List<String> mapBoundary) 
    this.mapBoundary = mapBoundary;


public String getSortBy() 
    return sortBy;


public void setSortBy(String sortBy) 
    this.sortBy = sortBy;


public String getSchLevel() 
    return schLevel;


public void setSchLevel(String schLevel) 
    this.schLevel = schLevel;


public String getSchType() 
    return schType;


public void setSchType(String schType) 
    this.schType = schType;


public Integer getSchRating() 
    return schRating;


public void setSchRating(Integer schRating) 
    this.schRating = schRating;


public Integer getListingWithinSchRadius() 
    return listingWithinSchRadius;


public void setListingWithinSchRadius(Integer listingWithinSchRadius) 
    this.listingWithinSchRadius = listingWithinSchRadius;


public String getSchId() 
    return schId;


public void setSchId(String schId) 
    this.schId = schId;


public String getSchWithinRadius() 
    return schWithinRadius;


public void setSchWithinRadius(String schWithinRadius) 
    this.schWithinRadius = schWithinRadius;


public Integer getListingWithinSkytrainStationRadius() 
    return listingWithinSkytrainStationRadius;


public void setListingWithinSkytrainStationRadius(Integer listingWithinSkytrainStationRadius) 
    this.listingWithinSkytrainStationRadius = listingWithinSkytrainStationRadius;


public Integer getListingWithinSkytrainStationTransitMinute() 
    return listingWithinSkytrainStationTransitMinute;


public void setListingWithinSkytrainStationTransitMinute(Integer listingWithinSkytrainStationTransitMinute) 
    this.listingWithinSkytrainStationTransitMinute = listingWithinSkytrainStationTransitMinute;


public Integer getSkytrainStationId() 
    return skytrainStationId;


public void setSkytrainStationId(Integer skytrainStationId) 
    this.skytrainStationId = skytrainStationId;


public Integer getSkytrainStationWithinRadius() 
    return skytrainStationWithinRadius;


public void setSkytrainStationWithinRadius(Integer skytrainStationWithinRadius) 
    this.skytrainStationWithinRadius = skytrainStationWithinRadius;



现在让我们在初始化对象时

Criteria.setPrice(1000.00);
Criteria.setListingKey("Key20120");
Criteria.setMlspId("Id2000");

所以这里总共 3 个参数将从 Criteria 对象中使用,其余的都将初始化为 NULL

现在,当我检查服务器日志时,它在此处检测到包括初始化值其余所有值也以 空白值

出现

那么我怎样才能防止这个 空白值 来自 Object 有没有像 JSON Object 这样的功能我们可以删除它。

【问题讨论】:

创建一个构造函数并传递所需的值。并且不要将列表初始化为 null。 @Duke1992:感谢您的回复,但是这里如何创建动态参数构造函数呢?最终我必须传递哪个参数它在这里不固定所以动态参数构造函数有什么解决方案吗? 查看***.com/a/19719701/3144174 只给所有变量默认赋空值。 @pRNaY:我做了人,但同样的事情发生了,看看当我检查日志时,我发现整个对象只添加了 3 个值,其余的都作为空白传递,所以你有什么解决方案来防止空白字段. 【参考方案1】:

也许您正在寻找的是创建自己的 TypeAdapter 并将其放在您的 Gson 转换器工厂中

public class CriteriaTypeAdapter extends TypeAdapter<Criteria>() 

  @Override
  public void write(JsonWriter out, Criteria value) throws IOException 
    out.beginObject();
    if (!Strings.isNullOrEmpty(value.getMlspId())) 
        out.name("mlsp_id");
        out.value(value.getMlspId());
    

    if (!Strings.isNullOrEmpty(value.getListing_key())) 
        out.name("listing_key");
        out.value(value.getListing_key());
    
    // ... and so on until last json field
    /* similar check for otherObject */         
    out.endObject();    
  

之后你就可以向 Gson 注册了。

//you can registerTypeAdapter multiple times
Gson gson = new GsonBuilder()
              .registerTypeAdapter(Criteria.class,new CriteriaTypeAdapter())
              .create();

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constants.BASE_URL_SERVICE)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

【讨论】:

以上是关于如何防止对象在 Retrofit2 的 API 调用中发送空字段的主要内容,如果未能解决你的问题,请参考以下文章

如何设计API接口,请求接口时需要进行身份验证,防止第三方随意调用接口?

如何在Android上通过retrofit2调用带有Cognito Credentials的API网关?

如何使用Retrofit2 API在RecyclerView中显示数据?

如何使用 Retrofit2 和 GSON 转换器解决“古怪”的 JSON API

如何在对象 Gson/Retrofit2 中获取字符串

Retrofit2:如何在具有不同字段名称的对象中接收 JSON 响应?