Posting to Ruby on Rails app from android
android, http, post, ruby-on-rails
Solution
You're setting a content-type of JSON but not actually sending JSON, you're sending standard POST url-encoded parameters.
You need to actually send a JSON object:
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);
Problem
So I am trying to post to a rails app from an Android app I am writing. I am able to post successful from inside the rails app. I was also able to post successfully using a chrome add on called Simple Rest client. When I try and post from the Android app its hitting the rails app but creating an empty post. None of the input data is being received by rails. I read that 3rd party applications are only able to GET from a Rails app depending on authentication so to make sure this wasn't the issue I was having I added this to my Rails config. ``` # de-activate tolken auth config.action_controller.allow_forgery_protection = false ``` At this point I am unsure as to where my issue lies, with my Rails backend or my Android client. ok so the Rails post method in my controller that I'm trying to reach is here ``` # 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 ``` Here is the Android java code for sending the Post Request. This is the method passing in the User input data I am trying to POST ``` 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(); } ``` And this is the class that it is passed to, permorming the 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; } } ``` This is the what log's out for postparams in the above class, so I know data is actually being sent ``` 04-03 21:36:23.994: I/postparams :(690): [drinks_id=41, name=Dave, paid=True] ``` This is what Log Cat is showing as a response from the server ``` 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"} ``` I am really struggling to understand where the issue lies with this and have been stuck on it for quite awhile. Any insight would be much appreciated. And if any more information is needed just shout. Edit: logs from server This is a successful post from the simple 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) ``` This is from the android app posting ``` 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 ```