2013-04-03 4 views
8

So versuche ich auf eine Rails-App von einer Android-App zu schreiben, die ich schreibe. Ich bin in der Lage, erfolgreich von innerhalb der Schienen App zu posten. Ich war auch in der Lage, erfolgreich eine Chrome-Erweiterung namens Simple Rest-Client zu veröffentlichen.Buchung in Ruby on Rails App von Android

enter image description here

Wenn ich versuche, und Post aus dem Android App seine der Rails-Anwendung schlägt aber eine leere Post zu schaffen. Keine der Eingabedaten wird von Rails empfangen.

Ich habe gelesen, dass 3rd-Party-Anwendungen nur in Abhängigkeit von der Authentifizierung von einer Rails-App abrufen können, um sicherzustellen, dass dies nicht das Problem war, das ich meiner Rails-Konfiguration hinzugefügt habe.

# de-activate tolken auth 
config.action_controller.allow_forgery_protection = false 

An dieser Stelle ich nicht sicher bin, wo mein Problem liegt, mit meinem Rails-Backend oder mein Android-Client.

ok so die Rails post-Methode in meinem Controller, die ich hier zu erreichen bin versucht

# POST /orders 
    # POST /orders.json 
    def create 
    @order = Order.new(params[:order]) 

    respond_to do |format| 
     if @order.save 
     format.html { redirect_to @order, notice: 'Order was successfully created.' } 
     format.json { render json: @order, status: :created, location: @order } 
     else 
     format.html { render action: "new" } 
     format.json { render json: @order.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

Hier ist der Android Java-Code für die Post-Anforderung senden. Dies ist die Methode in der Datenbenutzereingabe vorbei I

private void postInformationtoAPI() { 

       showToast("POSTING ORDER"); 
       List<NameValuePair> apiParams = new ArrayList<NameValuePair>(); 
       apiParams.add(new BasicNameValuePair("drinks_id", GlobalDrinkSelected)); 
       apiParams.add(new BasicNameValuePair("name", GlobalEditTextInputName)); 
       apiParams.add(new BasicNameValuePair("paid" , GlobalIsPaid)); 

       bgtPost = new BackGroundTaskPost(MAP_API_URL_POST_ORDER, "POST", apiParams); 
       bgtPost.execute(); 

       goToOrderCompleted(); 

      } 

Und das ist die Klasse POST versuche, dass es zu, übergeben wird permorming das HTTP-POST.

public class BackGroundTaskPost extends AsyncTask<String, String, JSONObject> { 

    List<NameValuePair> postparams = new ArrayList<NameValuePair>(); 
    String URL = null; 
    String method = null; 

    static InputStream is = null; 
    static JSONObject jObj = null; 
    static String json = ""; 

    public BackGroundTaskPost(String url, String method, List<NameValuePair> params) { 
     this.URL = url; 
     this.postparams = params; 
     this.method = method; 

     for (int i = 0; i < postparams.size(); i++){ 
      String test = postparams.get(i).toString(); 
      Log.d("This is in the lisht:", test); 
     } 
    } 

    @Override 
    protected JSONObject doInBackground(String... params) { 
     // TODO Auto-generated method stub 
     // Making HTTP request 
     try { 
     // Making HTTP request 
     // check for request method 

     if (method.equals("POST")) { 
     // request method is POST 
     // defaultHttpClient 

      DefaultHttpClient httpClient = new DefaultHttpClient(); 
      HttpPost httpPost = new HttpPost(URL); 
      httpPost.setEntity(new UrlEncodedFormEntity(postparams, HTTP.UTF_8)); 
      Log.i("postparams : ", postparams.toString()); 
      httpPost.setHeader("Content-Type", "application/json"); 
      httpPost.setHeader("Accept", "application/json"); 

      HttpResponse httpResponse = httpClient.execute(httpPost); 
      HttpEntity httpEntity = httpResponse.getEntity(); 
      is = httpEntity.getContent(); 

     } else if (method == "GET") { 
     // request method is GET 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     String paramString = URLEncodedUtils 
      .format(postparams, "utf-8"); 
     URL += "?" + paramString; 
     HttpGet httpGet = new HttpGet(URL); 

     HttpResponse httpResponse = httpClient.execute(httpGet); 
     HttpEntity httpEntity = httpResponse.getEntity(); 
     is = httpEntity.getContent(); 
     } 

     } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
     } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
     } catch (IOException e) { 
     e.printStackTrace(); 
     } 

     try { 
      Log.i("Logging out *is* before beffered reader", is.toString()); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(
     is, "utf-8"), 8); 
     Log.i("Logging out *is* after beffered reader", is.toString()); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
     sb.append(line + "\n"); 
     } 
     is.close(); 
     json = sb.toString(); 
     Log.i("json: ",json); 
     } catch (Exception e) { 
     Log.e("Buffer Error", "Error converting result " + e.toString()); 
     } 

     // try parse the string to a JSON object 
     try { 
     jObj = new JSONObject(json); 
     } catch (JSONException e) { 
     Log.e("JSON Parser", "Error parsing data TEST " + e.toString()); 
     } 

     // return JSON String 
     return jObj; 

    } 
    } 

Das ist das, was in der obigen Klasse für postparams aus Logbuch, damit ich weiß, Daten tatsächlich

geschickt wird
04-03 21:36:23.994: I/postparams :(690): [drinks_id=41, name=Dave, paid=True] 

Dies ist, was Log-Katze ist als Antwort vom Server zeigt

04-03 20:56:08.247: I/json:(690): {"created_at":"2013-04-03T20:56:06Z","drinks_id":null,"id":1351,"name":null,"paid":null,"served":null,"updated_at":"2013-04-03T20:56:06Z"} 

Ich kämpfe wirklich, um zu verstehen, wo das Problem liegt und stecken seit einer Weile fest. Jede Einsicht würde sehr geschätzt werden. Und wenn weitere Informationen benötigt werden, rufen Sie einfach.

Edit: Protokolle vom Server

Dies ist eine erfolgreiche Post von dem einfachen REST-Client

2013-04-03T23:13:31+00:00 app[web.1]: Completed 200 OK in 15ms (Views: 8.7ms | ActiveRecord: 5.2ms) 
2013-04-03T23:13:42+00:00 app[web.1]: Started POST "/orders.json" for 89.101.112.167 at 2013-04-03 23:13:42 +0000 
2013-04-03T23:13:42+00:00 app[web.1]: Processing by OrdersController#create as JSON 
2013-04-03T23:13:42+00:00 app[web.1]: Parameters: {"updated_at"=>nil, "drinks_id"=>51, "id"=>1021, "name"=>"Test", "paid"=>true, "served"=>nil, "created_at"=>nil, "order"=>{"drinks_id"=>51, "name"=>"Test", "paid"=>true, "served"=>nil}} 
2013-04-03T23:13:43+00:00 heroku[router]: at=info method=POST path=/orders.json host=fyp-coffeeshop.herokuapp.com fwd="89.101.112.167" dyno=web.1 connect=1ms service=25ms status=201 bytes=138 
2013-04-03T23:13:43+00:00 app[web.1]: Completed 201 Created in 15ms (Views: 0.6ms | ActiveRecord: 13.2ms) 

Dies ist aus dem Android App

2013-04-03T22:56:45+00:00 app[web.1]: Started POST "/orders.json" for 89.101.112.167 at 2013-04-03 22:56:45 +0000 
2013-04-03T22:56:45+00:00 app[web.1]: Processing by OrdersController#create as JSON 
2013-04-03T22:56:45+00:00 app[web.1]: Completed 201 Created in 23ms (Views: 2.2ms | ActiveRecord: 16.3ms) 
2013-04-03T22:56:45+00:00 heroku[router]: at=info method=POST path=/orders.json host=fyp-coffeeshop.herokuapp.com fwd="89.101.112.167" dyno=web.1 connect=4ms service=37ms status=201 bytes=138 
+0

Können Sie einen schnellen PHP-Skript schreiben die Parameterliste in der Post-Dump sich um sicherzustellen, dass es zu bekommen? Wirf das Array $ _POST in eine Datei und untersuche es. – Dave

+0

Ich dachte gerade mehr darüber nach. Ich habe nie eine Liste gesendet und gesagt, dass es JSON-Inhalt war, ich habe immer das JSONObject erstellt und dann das Name/Wert-Paar query = jsonobject gepostet, dann auf meinem Server den Abfragewert als JSON-String genommen. – Dave

+0

Ich werde gerade eine Anfrage vom Rest-Client und von meiner App für comparsion protokolliert, ich werde meine Frage aktualisieren – DavedCusack

Antwort

6

Sie Einstellung eines Content-Type von JSON, aber nicht wirklich das Senden JSON, Sie senden Standard-POST-URL-codierte Parameter.

Sie tatsächlich benötigen, um ein JSON-Objekt senden:

JSONObject params = new JSONObject(); 
params.put("drinks_id", GlobalDrinkSelected); 
params.put("name", GlobalEditTextInputName); 
params.put("paid", GlobalIsPaid); 

StringEntity entity = new StringEntity(params.toString()); 
httpPost.setEntity(entity); 
+0

Stimmt der Code in meiner Frage nicht mit den Parametern überein? die Methode postInformationtoAPI()? Edit: danke für die Hilfe übrigens – DavedCusack

+1

Cody vielen Dank haben Sie mir eine Menge Herzschmerzen gerettet. Durch das Eingeben des JSON-Objekts und das Hinzufügen dieses Objekts zur Entität "entity.setContentType (" application/json; charset = UTF-8 ");" Ich konnte auf dem Server posten – DavedCusack

1

Das Problem Posting ist, dass Sie, wenn Wenn Sie den POST in Android erstellen, überschreiben Sie die Entity (den Body). Sie legen es zunächst fest und dann setzen Sie es erneut und löschen so effektiv aus, was Sie bereits festgelegt haben.

Das ist richtig:

httpPost.setEntity(new UrlEncodedFormEntity(postparams)); 

Aber dann später ein paar Zeilen, die Sie überschreiben sie mit:

httpPost.setEntity(new StringEntity("UTF-8")); 

so dass 2. setEntity() Anruf Graben.

können Sie erreichen, was Sie versuchen zu tun - die POST-Körper in UTF-8 Einstellung von Ihrem Code zwicken wie:

httpPost.setEntity(new UrlEncodedFormEntity(postparams, HTTP.UTF_8)); 
+0

Vielen Dank für die Antwort Cody, ich verstehe, was Sie meinen und soll versuchen, es jetzt implementieren – DavedCusack

+0

Während ich sicher über das Aufrichten der Entität war nicht hilfreich, Die Parameter erreichen immer noch nicht Server. Ich muss auch etwas anderes falsch machen. Ich werde den Code in der Frage aktualisieren, um widerzuspiegeln, woran ich nicht arbeite – DavedCusack

+0

* Ich aktualisiere den Code in der Frage, um widerzuspiegeln, womit ich gerade arbeite – DavedCusack