最近在項目中使用到Retrofit來做網絡請求,Retrofit框架中有個非常好用的參數@body,該參數在做post請求的時候,能夠將封裝了請求參數的JavaBean對象 直接序列化然后發送到服務器,如圖一:
想一想,當你需要使用post請求向服務器提交一大堆數據(如圖二)的時候,你內心是不是崩潰的!
然而,當你配合Retrofit的@Body 你的接口請求可以寫成這樣(如圖三)!簡直就是藝術!有木有!有木有!
可是,這并不完美!如果你使用這種方式做Post請求,你可能會像我一樣,讓后端的童鞋感到莫名其妙,請求參數明明只有a,b,c;你傳過去的請求參數里面為什么除了a,b,c,還有一大丟亂七八糟的 e,f,g? 原因很簡單:因為我們封裝了參數的JavaBean 里面,往往會有一些我們不需要傳遞給服務器的參數數據 ,但確是需要存在的數據 ?比如圖三中用Order對象 在創建訂單的時候,他的id對于此次請求是多余的參數,但是在另外的一個獲取Order列表的請求中,這個id就能派上用場了;
所以問題來了(回歸正題^_^),我們能不能在向服務器提交請求的時候,將JavaBean在序列化的過程中剔除多余參數,然后又不影響請求的數據反序列化為JavaBean,好像很拗口,具體來說就是,比如這個Order對象在提交給服務器的時候,其序列化的過程中能不能過濾掉id參數,然后又不影響在獲取Order列表的時候 ?Json數據反序列化為Order對象的時候對id成員變量的賦值。
當然可以!使用@Expose 注解便可以實現(如圖四):
@Expose 有兩個參數 serialize 和 deserialize,即序列化與反序列化,當不指定的時候 默認都為true ; 而且該注解只在Gson通過
Gson gson=new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();方式創建的時候有效,也就是在通過Gson gson=new Gson()方式創建的時候,@Expose注解是無效的。也就是有沒有都一樣,切記!
圖四中 在Gson使用GsonBuilder創建下,Post請求中,id,code以及a字段會在序列化過程中過濾掉,也就是通過Retrofit向服務器提交Order對象的時候,服務器端只能接受到remark和list對應的數據 ,除此之外的字段因為在序列化的過程中被忽略而沒有提交給服務器。你可能注意到了list字段的@Expose注解 其deserialize=false, 這是因為我list字段在序列化的過程中是服務器需要的數據,但是在反序列化的過程中不希望他被賦值 所以在此進行了過濾。
也許有童鞋會問。還有其它方式沒有,答案是有的,Gson 序列化/反序列化過程中過濾指定字段的方式大概有四種,此處只是說到了其中的一種而已 ,其它的三種:排除transient字段;排除Modifier為指定類型的字段;使用ExclusionStrategy定制字段排除策略;
排除transient字段:給字段添加transient字段 然后在 序列化/反序列化過程中該字段都會被過濾 不能單獨對某一過程設置;
排除Modifier為指定類型的字段:通過Gson gson =newGsonBuilder().excludeFieldsWithModifiers(Modifier.PROTECTED) 方式獲取Gson并設置過濾域的修飾詞 ?此處為過濾protected修飾的字段 也是同時作用于序列化/反序列化 不能單獨對某一過程設置(待考證)
使用ExclusionStrategy定制字段排除策略:也是通過newGsonBuilder()來設置,自定義程度很高(等效于同時設置GsonBuilder的addSerializationExclusionStrategy和addDeserializationExclusionStrategy方法),詳情百度即可,在此就不作詳述了
OK,就講這么多吧;純手寫,如果對大家有用,別忘了星星我哦,嘿嘿. ?
PS.不足之處,還望指正,畢竟技術有限,期待大神們的指導 謝謝