找个理由
获取「新闻列表」的请求地址,一般我们是这样写的:
1
| String url = MobileApi.GET_NEWSES + "?channelID=" + mChannelID + "pageNo=" + mPageNo + "&pageSize=30";
|
这种写法其实不利于项目的后期维护,如果项目大规模地更改接口字段名,就要一个个文件去查找修改,单查找这步就消耗了很多时间,这显然不符合程序员懒惰的特性。我的做法是把请求参数实体化,并放到一个package下统一管理,以后要修改,直接去package下找到对应的参数(实体类)修改就可以了。
实体化请求参数后的写法:
1 2
| NewsParam param = new NewsParam(mChannelID, mPageNo); String url = MobileApi.GET_NEWSES + ParamFormatter.toUri(param);
|
具体实现
假设「获取新闻列表」请求接口地址为:http:localhost/getNewses?channelID=&pageNo=&pageSize
接口参数映射
1 2 3 4 5 6 7
| public class MobileApi {
public static final String HOST = "http:localhost/";
public static finsl String GET_NEWSES = HOST + "getNewses"; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class NewsParam {
@SerializedName("channelID") private int mChannelID;
@SerializedName("pageNo") private int mPageNo;
@SerializedName("pageSize") private int mPageSize = 30;
public NewsParam() {}
public NewsParam(int channelID, int pageNo) { mChannelID = channelID; mPageNo = pageNo; }
}
|
使用 Gson 的注解 SerializedName
将接口字段名称映射为自定义名称,如 channelID 映射为 mChannelID,这样如果接口字段名称改了,只需修改 SerializedName 的值即可,是不是很方便。
参数类型转换
做了接口参数名称映射后,下一步就是对 Get / Post
请求参数做类型转换了,我们把类型转换工作放到 ParamFormatter 中处理,下面是它的具体实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| public class ParamFormatter {
public static String toJson(Object object) { return new Gson().toJson(object); }
public static String toUri(Object object) { return generateUri("?", object); }
private static String generateUri(String prefix, Object object) { StringBuffer uriSb = new StringBuffer();
JSONObject jsonObject = null; Iterator<String> keys = null;
try { jsonObject = new JSONObject(toJson(object)); keys = jsonObject.keys();
while (keys.hasNext()) { String key = keys.next(); Object value = jsonObject.get(key);
key = URLEncoder.encode(key); value = URLEncoder.encode(String.valueOf(value));
uriSb.append("&").append(key).append("=").append(value); uriSb.replace(0, 1, prefix); } } catch (JSONException e) { e.printStackTrace(); }
return uriSb.toString(); }
@SuppressWarnings("unchecked") public static Map<String, String> toMap(Object object) { Map<String, String> map = new HashMap<String, String>();
JSONObject jsonObject = null; Iterator<String> keys = null;
try { jsonObject = new JSONObject(toJson(object)); keys = jsonObject.keys();
while (keys.hasNext()) { String key = keys.next(); String value = String.valueOf(jsonObject.get(key)); map.put(key, value); } } catch (JSONException e) { e.printStackTrace(); }
return map; }
}
|
零件组装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class NewsFragment extends CommonFragment {
private NewsParam mNewsParam;
@Override protected void initVariables(Bundle savedInstanceState) { mNewsParam = new NewsParam(); }
@Override protected String getUrl(int channelID, int pageNo) { mNewsParam.setChannelID(channelID); mNewsParam.setPageNo(pageNo); return MobileApi.GET_NEWSES + ParamFormatter.toUri(mNewsParam); } }
|