就算開發(fā) Android APP 也得懂一點(diǎn)API接口開發(fā)(一)引導(dǎo)前言

很多開發(fā) APP 的童鞋還只是會(huì)在 Android Studio 上寫一些 Java 代碼栋猖,對(duì) API 接口,服務(wù)之類的知之甚少,也對(duì) HTML/CSS/JS 一片朦朧,我覺得這是不好的火惊,擴(kuò)大知識(shí)面還是很有必要的,就算不能解決實(shí)際問題奔垦,有時(shí)候會(huì)提供一種解決問題的思路屹耐,比如某個(gè)產(chǎn)品老板要你一個(gè)月上線,怎么辦呢椿猎。原生代碼一行一行不知道要寫到什么時(shí)候去了惶岭,公司 UI,前端鸵贬,JS工程師一個(gè)都調(diào)動(dòng)不起來。相反如果了解快速開發(fā)技巧脖捻,混合開發(fā)之類的技術(shù)阔逼,就能減少很多工作量了。

我一直喜歡用 .NET 作為后端接口開發(fā)語言地沮,因?yàn)?.NET 開發(fā)效率確實(shí)非常高嗜浮,標(biāo)準(zhǔn)庫也非常成熟健全,不至于隨便什么都要第三方的摩疑,用它主要看中的就是在開發(fā)效率和工業(yè)標(biāo)準(zhǔn)能夠兩者都能兼顧的特點(diǎn)危融,我覺得還行。

很多人一打開 Visual Studio 就已經(jīng)啥了雷袋,創(chuàng)建項(xiàng)目都不知道點(diǎn)哪個(gè)吉殃,也不知道該創(chuàng)建什么類型的項(xiàng)目。是醬紫的,目前微軟主要是推 .NET Core 和 .NET Framework 的蛋勺,.NET Framework 是只能運(yùn)行在 Windows 平臺(tái)上的瓦灶,雖然在 Linux 上有 Mono Runtime 支持 .NET 程序的運(yùn)行,但是運(yùn)行效率比 .NET 在 Windows 上的還是有些差距抱完。.NET Core 是微軟推出的下一代編程框架贼陶,在1.X 版本的時(shí)候,只能支持開發(fā) Web 和 CLI 程序巧娱,不過如今可以開發(fā) WPF 桌面程序了碉怔,雖然目前還只能在 Windows 上運(yùn)行,但是誰知道以后會(huì)不會(huì)在 Linux 上也實(shí)現(xiàn)了桌面 GUI 環(huán)境呢禁添。

.NET Core 很好撮胧,網(wǎng)上教程也很多,這個(gè)是灰常建議去學(xué)習(xí)的上荡,不過我還是比較習(xí)慣用 ASP.NET MVC 和 WebForm 方式趴樱,當(dāng)然拖控件是不可能拖控件了,這輩子都不可能拖控件酪捡,就是用用一般處理程序?qū)憣懡涌谌鳎拍芫S持得了生活的樣子。

既然是服務(wù)接口逛薇,那就意味著沒有什么界面捺疼,或者及少量的界面,用一般處理程序是墜吼的永罚。

創(chuàng)建一個(gè) ASP.NET Web 應(yīng)用程序 (.NET Framework)啤呼,然后選擇空項(xiàng)目,下一步就可以了呢袱。

接下來需要?jiǎng)?chuàng)建一個(gè) HttpHandler 的實(shí)現(xiàn)類官扣,并稍作封裝,讓它成為我們接口的基礎(chǔ)類羞福,因?yàn)橹苯邮褂?HttpHandler 是不那么友好的惕蹄,目前不需要了解為什么要這么做。

如果是為了考慮穩(wěn)定性治专,不那么在乎性能卖陵,可以將整個(gè) ProcessRequest 都用 Try Catch 包裹,避免因?yàn)榻涌谥械腻e(cuò)誤张峰,導(dǎo)致 APP 未能處理正確的返回而導(dǎo)致閃退泪蔫,雖然這種辦法很挫,但是我很喜歡用喘批。

 public void ProcessRequest(HttpContext context)
 {

     if (context.Request.RequestType != "POST")
     {
         context.Response.StatusCode = 405;
         return;
     }

     AllowCrossDomain = true;
     TryExecute.Execute(() =>
     {
         Context = context;
         ProcessUserRequest();
     }, error =>
      {
          bool processed = false;

          if (error is SilverStarAmsException)
          {
              var serror = error as SilverStarAmsException;
              if (serror != null)
              {
                  ResponseAsErrorJson(serror.ErrorCode, serror.Message);
                  processed = true;
              }
          }

          if (!processed)
          {
              ResponseAsErrorJson(-11, "process api request error");
          }
      });
 }

其次撩荣,API 接口或許會(huì)被小程序或其它服務(wù)用到铣揉,我們對(duì)其做一個(gè)跨域的測(cè)試,在 Header 頭輸出對(duì)應(yīng)的消息婿滓,客戶端即可實(shí)現(xiàn)跨域請(qǐng)求老速,這時(shí)的客戶端通常是瀏覽器,因?yàn)闉g覽器為了安全性會(huì)設(shè)置同源策略凸主,如果接口不支持跨域橘券,接口就不能被使用。

在 ASP.NET 里設(shè)置 Header 有很多種方法卿吐,為了適應(yīng) IIS 的經(jīng)典和集成模式旁舰,以及或許有其他 Web 容器的支持,我都會(huì)寫一遍嗡官,哪種支持就是用哪種箭窜,然后就有了下面的奇怪的代碼:

protected void AppenHeader(string key, string value)
{

    bool done = false;

    try
    {
        Context.Response.AppendHeader(key, value);
        done = true;
    }
    catch
    {

    }

    if (!done)
    {
        try
        {
            Context.Response.Headers.Add(key, value);
            done = true;
        }
        catch
        {

        }
    }

    if (!done)
    {
        try
        {
            Context.Response.AddHeader(key, value);
            done = true;
        }
        catch
        {

        }
    }
}

對(duì)于 APP 接口來說穴张,通常是不會(huì)或者對(duì)于安全性很低的情況下才會(huì)用到 GET 請(qǐng)求毒坛,當(dāng)然合服 Restful 規(guī)范的可能也會(huì)用的多,比如訂單的增刪改查:

PUT /api/order
DELETE /api/order/12
PATCH /api/order/12
GET /api/order/12

如果覺得不需要這么多的 HTTP 謂詞磅网,只用 POST 也是可以的婆咸。

我上家公司的 APP 接口全部是這種實(shí)現(xiàn)竹捉,好吧,其實(shí)都是我實(shí)現(xiàn)的尚骄,雖然只有數(shù)十萬用戶块差,但是目前來看,這種架構(gòu)還能支撐倔丈,而且這也不是性能的瓶頸憨闰,只能說在可維護(hù)性上斷然沒有 Restful 方式的好。

接下來我需要建立一個(gè)數(shù)據(jù)庫需五,繼續(xù)是 .NET 當(dāng)然配合 MSSQL 是墜吼的了鹉动,設(shè)計(jì)數(shù)據(jù)庫和表此處略去不表,ORM 我是用 EntityFramework 6.x 宏邮。

以一個(gè)簡(jiǎn)單例子泽示,在數(shù)據(jù)庫中創(chuàng)建了一個(gè) Category 表,表示文章或者某種物體的分類蜀铲,現(xiàn)在要在 APP 里獲取 Category 列表边琉,每頁顯示 20 條數(shù)據(jù)属百,或者由 APP 指定參數(shù)记劝。

創(chuàng)建一個(gè)一般處理程序,GetCategory.ashx 族扰,繼承剛才上面的自定義的 Handler厌丑,重寫 ProcessUserRequest 接口定欧。

聲明三個(gè)參數(shù),表示總頁數(shù)怒竿,當(dāng)前頁碼砍鸠,分頁大小:

  int page, pageSize, totalPage;

對(duì)于數(shù)據(jù)庫的訪問耕驰,其實(shí)超簡(jiǎn)單爷辱,看我怎么查出所有數(shù)據(jù):

totalPage = (int)(Math.Ceiling((double)all.Count() / pageSize));

if (page > totalPage) page = totalPage;
if (page < 1) page = 1;

var data = all.OrderByDescending(s => s.CategoryLastChangeDate).Skip((page - 1) * pageSize).Take(pageSize).ToList();

然后輸出查詢出當(dāng)前頁的數(shù)據(jù),并輸出到 JSON朦肘,對(duì)象轉(zhuǎn)為 JSON 饭弓,并不能保證是 100% 成功的,對(duì)于 APP 的接口服務(wù)來說媒抠,穩(wěn)定性最重要弟断,就算是接口出錯(cuò),也必須得返回出錯(cuò)代碼趴生,所以前面的 Handler 的子類有一個(gè)超大的 Try 阀趴,對(duì)于 JSON 輸出,也應(yīng)如此苍匆。

protected void ResponseAsJson(object data)
{
    string json = "[]";

    TryExecute.Execute(() =>
    {
        json = Newtonsoft.Json.JsonConvert.SerializeObject(data);

    }, error =>
    {
        json = GetGenericErrorJson(-10, "serialize data error");
    });

    ResponseAsJsonString(json);
}

完整的接口代碼如下:

/// <summary>
/// GetCategory 的摘要說明
/// </summary>
public class GetCategory : Core.SilverCoreHandlerBase
{

    public override void ProcessUserRequest()
    {
        base.ProcessUserRequest();

        int page, pageSize, totalPage;

        page = (Context.Request["page"] + "").AsInt(0);
        pageSize = (Context.Request["page_size"] + "").AsInt(0);

        if (page < 1) page = 1;
        if (pageSize < 1 || pageSize > 50) pageSize = 50;

        var db = new Data.SilverStarDB();
        var all = db.KoteiAssetCategory;

        totalPage = (int)(Math.Ceiling((double)all.Count() / pageSize));

        if (page > totalPage) page = totalPage;
        if (page < 1) page = 1;

        var data = all.OrderByDescending(s => s.CategoryLastChangeDate).Skip((page - 1) * pageSize).Take(pageSize).ToList();
        ResponseAsJson(new { page = page, total_page = totalPage, data = data });

    }
}

F5 執(zhí)行看看刘急,會(huì)提示不支持的謂詞,當(dāng)然了锉桑,只支持 POST 的芭琶埂!可以用 POSTMAN 工具調(diào)試民轴。

好了攻柠,看看最終輸出的 JSON 結(jié)果:

如此,在 APP 中使用相關(guān)的 HTTP 庫后裸,就可以完成接口的調(diào)用了瑰钮,敲你嗎簡(jiǎn)單!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末微驶,一起剝皮案震驚了整個(gè)濱河市浪谴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌因苹,老刑警劉巖苟耻,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異扶檐,居然都是意外死亡凶杖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門款筑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來智蝠,“玉大人腾么,你說我怎么就攤上這事¤就澹” “怎么了解虱?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長漆撞。 經(jīng)常有香客問我殴泰,道長,這世上最難降的妖魔是什么浮驳? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任艰匙,我火速辦了婚禮,結(jié)果婚禮上抹恳,老公的妹妹穿的比我還像新娘员凝。我一直安慰自己,他們只是感情好奋献,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布健霹。 她就那樣靜靜地躺著,像睡著了一般瓶蚂。 火紅的嫁衣襯著肌膚如雪糖埋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天窃这,我揣著相機(jī)與錄音瞳别,去河邊找鬼。 笑死杭攻,一個(gè)胖子當(dāng)著我的面吹牛祟敛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播兆解,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼馆铁,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了锅睛?” 一聲冷哼從身側(cè)響起埠巨,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎现拒,沒想到半個(gè)月后辣垒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡印蔬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年勋桶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡哥遮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出陵究,到底是詐尸還是另有隱情眠饮,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布铜邮,位于F島的核電站仪召,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏松蒜。R本人自食惡果不足惜扔茅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秸苗。 院中可真熱鬧召娜,春花似錦、人聲如沸惊楼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽檀咙。三九已至雅倒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弧可,已是汗流浹背蔑匣。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棕诵,地道東北人裁良。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像校套,于是被迫代替她去往敵國和親趴久。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 承接上一篇文章搔确,接下來會(huì)說些非常簡(jiǎn)單的例子彼棍,也比較符合 Restful API 的規(guī)范,并且會(huì)選用 .NET Co...
    天兵公園閱讀 1,991評(píng)論 0 12
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,111評(píng)論 1 32
  • Awesome DotNet膳算,這又是一個(gè) Awesome XXX 系列的資源整理座硕,由 quozd 發(fā)起和維護(hù)。內(nèi)容...
    小明yz閱讀 3,700評(píng)論 0 47
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5涕蜂? 答:HTML5是最新的HTML標(biāo)準(zhǔn)华匾。 注意:講述HT...
    kismetajun閱讀 27,513評(píng)論 1 45
  • 2018年10月31日 星期三 天氣晴 親子日記第176篇 大寶期中考試的成績(jī)出來了,比我想象的差了太遠(yuǎn)。...
    最愛奇毅閱讀 134評(píng)論 0 1