Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android移動開發學習筆記(二)神奇的Web API

android移動開發學習筆記(二)神奇的Web API

編輯:關於Android編程

本次分兩個大方向去講解Web Api,1、如何實現Web Api?2、如何Android端如何調用Web Api?對於Web Api是什麼?有什麼優缺點?為什麼用WebApi而不用Webservice?這些問題都不去解答,百度一下,關於這方面的資料很多,就不再去啰嗦。

一、如何在web端實現WebApi

(1)如何新建一個WebApi?

在上一章中,講到我們項目用的是.net 4.5,開發工具是Visual Studio 2012,在Visual Studio 2012中新建MVC4項目,選擇Web API,然後項目生成,如下圖一、圖二、圖三所示, 和普通的MVC項目相比,它繼承了ApiController,然後我們運行一下項目,在浏覽器裡輸入http://localhost:56091/api/values/get?id=5,如圖四所示,即成功調用了項目默認寫的Get方法實例,有數據返回即表示調用成功!

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316364863.png

(圖一)

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316365009.png

(圖二)

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316365088.png

(圖三)

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316365135.png

(圖四)

(2)Get和Post數據?

(2.1) Get方法

具體什麼是Get就不再啰嗦了,可以自己百度查看, 使用 [HttpGet]標識,當然也可以不用加,只需要方法名用Get開頭,Get方法是使用Url參數傳遞的,不能接收實體參數,如:http://localhost:56091/api/values/get?id=5,id即是參數,當然也可以多參數,如:http://localhost:56091/api/values/get?id=5&name=tim ,默認參數使用[FromUri]

Get是有長度限制的,參數不能過多,而且參數暴露在外面,容易被人很方便的截取。

(2.2)Post方法

使用 [HttpPost]方式傳遞,當然也可以不用加,只需要方法名用Post開頭,Post方法可以使用Url傳遞參數,也可以用Body傳遞參數,默認參數使用[FromUri],可以加[FromBody]接收body裡傳遞的參數,但是有問題的是,我使用[FromBody]方式,參數為空,根本接收不動值,上網查了資料,很多人遇到問題,不知道是不是Web Api本身的問題,無奈只好使用下面最原始的方式了,獲取Body的值了。

            HttpContextBase context = (HttpContextBase)Request.Properties[MS_HttpContext];//獲取傳統context
            HttpRequestBase request = context.Request;//定義傳統request對象
            string name = request.Form.Keys[0];
            if (name == null)
            {
                name = request.Form[0];
            }

另外Post的方法不能直接在浏覽器裡敲地址獲取數據,調試起來不是很方便,所以用了一個工具,火狐浏覽器可以安裝一個插件,叫Poster,如下圖六所示,測試起來很方便。

 

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316365291.png

(圖五)

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316365268.png

(圖六)

(3)Json數據格式?

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,易於人閱讀和編寫,同時也易於機器解析和生成。

Json數據格式傳輸是目前接口數據傳輸主流,本次我們的項目也是使用Json格式數據,我們所有的接口參數都是統一的參數名,後面跟的是Json格式字符串,如:http://localhost:8010/api/MobileInfo/Get_Welcome? params=JsonString,這是接口的調用,接口返回結果也是Json格式。

如下圖七所示,使用Newtonsoft.Json類庫,這是VS項目集成的類庫,可以很方便的使用JsonConvert.SerializeObject(value)方法,將object對象轉換為Json格式。

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316365254.png

(圖七)

                //step2:參數反序列化
                T transferObj = default(T);
                transferObj = Newtonsoft.Json.JsonConvert.DeserializeObject(JsonString);

 

(4) 路由的配置

如下圖八所示,默認路由配置是這樣,只會找到Controller,不用根據Action去分配地址,所以相同Controller下只會找到Get方法或Post方法,不管你方法名是否相同,這樣很明顯不能滿足我們的需求,如果想以Action去標識地址,就用下面代碼配置:

config.Routes.MapHttpRoute(
    name: CommonApi,
    routeTemplate: api/{controller}/{action}/{id},
    defaults: new { id = RouteParameter.Optional }
);

 

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316365347.png

(圖八)

 

二、如何在Android端調用WebApi

(1)調用web Api的Get方法

    public void getAnnouncement(final Object reqTag, final WSAnnouncementListCb cb) {

         //需要調用WebApi的Url地址  參數用UTF-8編碼        String url = Constants.WEB_BASE_URL
                + MobileInfo/Get_AnnouncementList?JsonString=
                + Utils.getEncodingParamsString((Object) UserManager.getInstance()
                        .getLoginedUserInfo());

        //使用Request對象,請求數據  Mdthod.Get WsAnnouncementListRsp.class接收結果的對象實體類        GsonRequest gsonRequest = new GsonRequest(
                Method.GET, url, WSAnnouncementListRsp.class,
                new Response.Listener() {
                    @Override
                    public void onResponse(WSAnnouncementListRsp rsp) {
 		        //返回的Json格式數據,經過反序列化後的對象實體                        if (cb != null) {
                            cb.onResponse(Utils.stringToInteger(rsp.message.ResultCode), rsp);
                        }
                    }

                }, errorListener(true));

        gsonRequest.setRequestTag(reqTag);

        RequestManager.addRequest(gsonRequest, reqTag);
    }

Android反序列化Json的方法:

當然下面代碼中包含判斷Token是否過期,過期之後重新登錄,因為判斷Token是否過期是每個App接口都可能要考慮的事情,所以就沒有刪除,以供大家參考。

 //Response的時候,返回解析後的對象
 protected Response parseNetworkResponse(NetworkResponse response) {
        try {

		    //接收到的Json格式數據字符串
            String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
			//如果有轉義字符就替換她
            json = json.substring(1, json.length() - 1);
            json = json.replace(\, );
            Log.I(L, Response type: + mClazz.getName() + Parsed Json Buffer:  + json);
			
            //反序列化Json數據
            WSBaseResponse baseResponse = (WSBaseResponse) mGson.fromJson(json, mClazz);
            //判斷Token是否過期
            if (Utils.stringToInteger(baseResponse.message.ResultCode) == Constants.ERR_TOKEN_INVALID) {
//                Log.I(L, get token status: + UserManager.getInstance().getTokenStatus());
//                if (UserManager.getInstance().getTokenStatus() != TOKEN_STATUS.TOKEN_GETTING) {
//                    Log.I(L,set token status: + TOKEN_STATUS.TOKEN_EXPIRED);
//                    UserManager.getInstance().setTokenStatus(TOKEN_STATUS.TOKEN_EXPIRED);
//                }

                synchronized (GsonRequest.class) {
                    if (UserManager.getInstance().getTokenStatus() != TOKEN_STATUS.TOKEN_GETTING) {
                        Log.I(L,  relogin ...);
                                           
                        RequestManager.addCachedRequest(this);

                        UserManager.getInstance().relogin(new OnLoginListener() {

                            @Override
                            public void onLogin(int result, String message) {
                                if (result == UserManager.LOGIN_RESULT_OK) {
                                    Log.I(L, Login suceesss);
                                    
                                    UserManager.getInstance().setTokenStatus(TOKEN_STATUS.TOKEN_OK);
                                  
                                    
                                } else {
                                    Log.I(L,Login failed...);
                                    // Show login activity
                                    UserManager.getInstance().setTokenStatus(TOKEN_STATUS.TOKEN_FAIL);
                                    MyActivityManager.getInstance().finishAllActivity();
                                    showLoginActivity();
                                }
                            }
                        });
                    } else {
                        //
                        Log.I(L, prepare resend request);
                       // reSendRequest();
                        RequestManager.addCachedRequest(this);
                    }

                }

                return Response.error(new TokenExpiredError());
            } else {

			    //返回泛型對象
                return Response.success((T) baseResponse/*
                                                         * mGson.fromJson(json,
                                                         * mClazz)
                                                         */,
                        HttpHeaderParser.parseCacheHeaders(response));
            }

        } catch (UnsupportedEncodingException e) {
            Log.E(L, response parse error: + mClazz.getName());
            return Response.error(new ParseError(e));
        } catch (JsonSyntaxException e) {
            Log.E(L, response parse error: + mClazz.getName());
            return Response.error(new ParseError(e));
        }
    }

 

(2)調用web Api的Post方法

放在Url裡的和Get方法一樣調用,只是傳參的時候,把Method.Get改為Method.Post方式,

因此主要講Post的Body方法

    public void updateUserInfo(final Object reqTag, final WSUpdateUserInfoReq req,
            final WSUpdateUserInfoCb cb) {

        setUserIdAndTokenForReq(req);

        // post Url不帶任何參數
        String url = Constants.WEB_BASE_URL + MobileInfo/Save_EmployeeInfo;
	//req是參數
        GsonRequest gsonRequest = new GsonRequest(
                Method.POST, url,Utils.getEncodingParamsString((Object) req), WSCommonRsp.class,
                null, new Response.Listener() {
                    @Override
                    public void onResponse(WSCommonRsp rsp) {
                        if (cb != null) {
                            cb.onResponse(Utils.stringToInteger(rsp.message.ResultCode), rsp);
                        }
                    }

                }, errorListener(true));

        gsonRequest.setRequestTag(reqTag);

        RequestManager.addRequest(gsonRequest, reqTag);

    }

 

以上就是App接口的實現和接口在Android中的調用方法,我提供的都是一些偽代碼,主要是講解功能實現的思想和用到哪些重要的類方法。下章則正式學習Android開發,看一個零基礎的菜鳥如何快速上手做開發的。

 

 

 

 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved