使用 Android 客戶端向 Ruby on rails 構建的 Web Application 提交 HTTP GET 和 HTTP POST 請求

最近想弄個能訪問 Internet 的 Android 應用,由於求快因此用了 Ruby on Rails 來提供 HTTP 資源。這方面的資料仍是比較少的,因此把嘗試的過程記錄下來。html

 

1 使用 Ruby on Rails 構建 Web Application

 

1.1 新建 Web Application

rails new Test 
cd Test

1.2 生成 product

rails generate scaffold product reference:string quantity:decimal
rake db:migrate

 啓動服務android

rails server

 打開http://localhost:3000/productsjson

 應該能夠看到如下信息(這個就是GET的結果啦,只不過如今尚未記錄):ruby

 在網頁上添加一條記錄,單擊「New Product」,會轉到「http://localhost:3000/products/new」,在裏面填寫信息後單擊「Greate Product」(這樣就提交了一個 POST):網絡

也就是說,網頁端的 GET 和 POST 都是能夠執行的。app

 

1.3 使用 Json 格式傳輸數據

先試試 GET Json 格式的數據

打開:http://localhost:3000/products/1.jsonide

能夠看到,使用 ruby on rails 是能夠直接得到 Json 數據的,這是爲何呢?工具

爲了弄清楚 Json 數據是怎麼來的,先查看 routes測試

rake routes

顯示出如下結果:url

因此輸入的 http://localhost:3000/products/1.json 對應的是 Controller 裏面的 show,在代碼裏找到show(Test/app/controllers/products_controller.rb):

咦!什麼狀況?啥都不寫就能直接支持 Json ?這也太牛逼了吧。

 

再試試 Post Json 格式的數據

前面已經知道,用網頁能夠提交一個 POST,先跟蹤一下下這個 POST,用開發者工具查看網絡知道頁面提交的時候提交了一個 POST:

這個 POST 根據前面的 Routes 應該是給了 controller 裏的 create。

因此是 @product = Product.new(product_params) 建立對象,@product.save 保存對象。。那麼 product_params 怎麼來的呢?

好吧,是這樣來的。。。

 

嗯。。仍是沒有解決我想要的 Json 傳輸方法,後來仍是搜索找大神。。。

在 Test/app/controllers/products_controller.rb 中添加如下代碼,用於接受 Android App 提交的 Json 數據。

  def create_from_app
      data_json=JSON.parse request.body.read
      @product = Product.new(data_json)
      @product.save
  end

 

1.4 測試 GET 和 POST 是否正常

測試使用的是火狐的 Poster 工具。

測試 GET

測試 POST

補上一段小插曲:直接提交 POST 時是出錯的:

把出錯的內容粘貼出來存成html,發現是這個錯誤:

百度求大神,獲得這樣的答案:

這是從rails 2.0 開始包含的一個新功能,目的在於防止CSRF(Cross-Site Request Forgery)攻擊

有這樣幾種解決方式

請原諒我直接暴力地選擇了禁用 CSRF 的方式,找到Test/app/controllers/products_controller.rb,插入代碼

  protect_from_forgery :except => :index  
  
  # you can disable csrf protection on controller-by-controller basis:  
  skip_before_filter :verify_authenticity_token  

重啓 rails server

問題解決,再次提交 POST:

也就是說 Android 客戶端只要能按照以上格式發送 HTTP 請求就能夠了。

 

 

2 使用 Android 客戶端訪問 HTTP 資源

 

2.1 獲取訪問網絡的權限

在 AndroidManifest.xml 文件中添加如下行

<uses-permission android:name="android.permission.INTERNET"/>

 

2.2 使用 Android 客戶端提交 GET 請求

        try {
            final String url = "http://192.168.0.138:3000/products/" + message
                    + ".json";

            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        HttpGet httpGet = new HttpGet(url);
                        HttpResponse httpResponse = new DefaultHttpClient()
                                .execute(httpGet);
                        if (httpResponse.getStatusLine().getStatusCode() == 200) {
                            result = EntityUtils.toString(httpResponse
                                    .getEntity());

                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            thread.start();
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

 

2.3 使用 Android 客戶端提交 POST 請求

try{
        Thread threadPost = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    final String url = "http://192.168.0.138:3000/products";
                    HttpPost httpPost = new HttpPost(url);
                    
                    JSONObject json = new JSONObject();
                    json.accumulate("reference", "888");
                    json.accumulate("quantity", "8");
                    JSONObject response = null;
                    StringEntity s = new StringEntity(json.toString());
                    s.setContentEncoding("UTF-8");
                    s.setContentType("application/json");
                    httpPost.setEntity(s);
                    
                    HttpResponse httpResponse = new DefaultHttpClient()
                            .execute(httpPost);
                    if (httpResponse.getStatusLine().getStatusCode() == 200) {
                        result = EntityUtils.toString(httpResponse.getEntity());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        threadPost.start();
        threadPost.join();
        } catch (Exception e) {
            e.printStackTrace();
        }
相關文章
相關標籤/搜索