i trying post json array rails web service. works fine json object. json array getting null result.
here code:
1. creating json array
jsonarray tickerarray = new jsonarray(); for(int = 0; < 3; i++) { jsonobject jsonobjforarray = new jsonobject(); jsonobjforarray.put("activity_id", "10100"); jsonobjforarray.put("player_id", i); jsonobjforarray.put("time", * 100 + * 5); jsonobjforarray.put("game_id", game_id); tickerarray.put(jsonobjforarray); } log.i(tag, tickerarray.tostring(2));
with following result:
[ { "activity_id": "10100", "player_id": 0, "time": 0, "game_id": "6", }, { "activity_id": "10100", "player_id": 1, "time": 105, "game_id": "6", }, { "activity_id": "10100", "player_id": 2, "time": 210, "game_id": "6", } ]
2. send httppostrequest
defaulthttpclient httpclient = new defaulthttpclient(); httppost httppostrequest = new httppost(url); stringentity se = new stringentity(tickerarray.tostring()); // set http parameters httppostrequest.setentity(se); httppostrequest.setheader("accept", "application/json"); httppostrequest.setheader("content-type", "application/json"); long t = system.currenttimemillis(); httpresponse response = (httpresponse) httpclient.execute(httppostrequest); httpentity entity = response.getentity(); if (entity != null) { inputstream instream = entity.getcontent(); header contentencoding = response.getfirstheader("content-encoding"); if (contentencoding != null && contentencoding.getvalue().equalsignorecase("gzip")) { instream = new gzipinputstream(instream); } string resultstring= convertstreamtostring(instream); instream.close(); log.i("resultstring", resultstring); ...
my resultstring:
{"activity_id":null,"created_at":"2016-01-29t09:55:49z","game_id":null,"id":450,"player_id":null,"time":null,"updated_at":"2016-01-29t09:55:49z"}
everything null except "id", "created_at", "updated_at". on web service got one (instead of three) new empty entry.
what went wrong? thank help.
edit - rails controller
# post /ticker_activities # post /ticker_activities.json def create puts params @ticker_activity = tickeractivity.new(params[:ticker_activity]) respond_to |format| if @ticker_activity.save format.html { redirect_to @ticker_activity, notice: 'ticker created.' } format.json { render json: @ticker_activity, status: :created, location: @ticker_activity } else format.html { render action: "new" } format.json { render json: @ticker_activity.errors, status: :unprocessable_entity } end end end
edit ii - passed json array , handling
after placing puts params
in create method result in logs:
{"_json"=>[{"activity_id"=>"10100", "player_id"=>0, "time"=>0, "game_id"=>"6"}, {"activity_id"=>"10100", "player_id"=>1, "time"=>105, "game_id"=>"6"}, {"activity_id"=>"10100", "player_id"=>2, "time"=>210, "game_id"=>"6"}], "action"=>"create", "controller"=>"ticker_activities", "format"=>"json", "ticker_activity"=>{}}
so passing android rails seems ok. question how handle in rails?! found solution importing csv files:
def self.import(file) csv.foreach(file.path, headers: true) |row| ticker_hash = row.to_hash tickeractivity.create!(ticker_hash) end end
is there similar json arrays?
your rails controller expects params hash this:
{ ticker_activity: { activity_id: "10100", player_id: 0, time: 0, game_id: "6", } }
check placing puts params
on first line of create
action in controller. if isn't you'll have change either client side send appropriate json server expects or server side handle arrays.
re edit ii:
to convert params you're getting post android, following:
params["_json"].each |params_hash| ticker = tickeractivity.create!(params_hash) end
however, should careful here; passing params without whitelisting them leaves open mass assignment attack. rails recommends using strong parameters avoid (read more here: http://edgeguides.rubyonrails.org/action_controller_overview.html#strong-parameters), i'd recommend doing instead.
params["_json"].each |params_hash| whitelisted_params = params_hash.permit(:activity_id, :player_id, :time, :game_id) ticker = tickeractivity.create!(whitelisted_params) end
the convention in rails follow restful routing , convention create action save single resource (i.e. single ticker_activity). therefore i'd suggest create entirely new controller action in rails controller handle creation of multiple ticker activities.
add following line rails app's routes.rb file:
post '/multiple_ticker_activities', to: 'ticker_activities#create', as: :multiple_ticker_locations
then change android app post json data
/multiple_ticker_activities.json
.and add following new controller action.
# post /multiple_ticker_activities # post /multiple_ticker_activities.json def create_multiple puts params @ticker_activities = params["_json"].map |params_hash| whitelisted_params = params_hash.permit(:activity_id, :player_id, :time, :game_id) tickeractivity.new(whitelisted_params) end respond_to |format| # check ticker_activities valid , can saved if @ticker_activities.all? { |ticker_activity| ticker_activity.valid? } # know valid, save each ticker_activity @ticker_activities.each |ticker_activity| ticker_activity.save end # , respond json versions of saved ticker_activites format.json { render json: @ticker_activities, status: :created, location: multiple_ticker_locations_url } else # since @ least of ticker_activities invalid, # can't save *all* ticker_activities, # respond validation errors instead @errors = @ticker_activities.map { |ticker_activity| ticker_activity.errors } format.json { render json: @errors, status: :unprocessable_entity } end end end
(note: controller action handles json formatted requests. doesn't handle html formatted requests. won't need handle html requests if only android app using action. however, if that's not case , want handle html you'll first need decide redirect following successful save. because don't know how app structured, , don't need handle html anyway, left out html support).
this should fix problem (unless i've made typos).
Comments
Post a Comment