[英]Return Http error responses to API json
My rails application returns the http 200 code fine but if there is an error I want my controller to pass the error to JSON so I can deal with it in my Android application. 我的Rails应用程序可以正常返回http 200代码,但是如果出现错误,我希望控制器将错误传递给JSON,以便可以在Android应用程序中进行处理。
If a vote is successful I get the following in my rails server: 如果投票成功,我将在Rails服务器中获得以下信息:
Started PUT "/articles/10/dislike" for 49.199.139.48 at 2016-03-18 11:46:08 +0000
Cannot render console from 49.199.139.48! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by ArticlesController#downvote as JSON
Parameters: {"votes"=>{"votable_id"=>"10", "votable_type"=>"Article", "voter_id"=>"3", "voter_type"=>"User", "vote_flag"=>"f", "vote_weight"=>"1"}, "article"=>"10", "id"=>"10"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? ORDER BY "users"."id" ASC LIMIT 1 [["email", "adam1st@hotmail.com"]]
Article Load (0.2ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = ? ORDER BY "articles"."created_at" DESC LIMIT 1 [["id", 10]]
(0.2ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."voter_id" = ? AND "votes"."voter_type" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 10], ["votable_type", "Article"], ["voter_id", 3], ["voter_type", "User"]]
ActsAsVotable::Vote Load (0.2ms) SELECT "votes".* FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."voter_id" = ? AND "votes"."voter_type" = ? AND "votes"."vote_scope" IS NULL ORDER BY "votes"."id" DESC LIMIT 1 [["votable_id", 10], ["votable_type", "Article"], ["voter_id", 3], ["voter_type", "User"]]
(0.2ms) begin transaction
(0.1ms) commit transaction
Completed 200 OK in 12ms (Views: 0.2ms | ActiveRecord: 1.1ms)
If it is unsuccessful (because the person has voted already) I get the following: 如果不成功(因为该人已经投票),我将得到以下信息:
Started PUT "/articles/10/dislike" for 49.199.139.48 at 2016-03-18 11:46:53 +0000
Cannot render console from 49.199.139.48! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by ArticlesController#downvote as JSON
Parameters: {"votes"=>{"votable_id"=>"10", "votable_type"=>"Article", "voter_id"=>"3", "voter_type"=>"User", "vote_flag"=>"f", "vote_weight"=>"1"}, "article"=>"10", "id"=>"10"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? ORDER BY "users"."id" ASC LIMIT 1 [["email", "adam1st@hotmail.com"]]
Article Load (0.3ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = ? ORDER BY "articles"."created_at" DESC LIMIT 1 [["id", 10]]
(0.3ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."voter_id" = ? AND "votes"."voter_type" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 10], ["votable_type", "Article"], ["voter_id", 3], ["voter_type", "User"]]
ActsAsVotable::Vote Load (0.4ms) SELECT "votes".* FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."voter_id" = ? AND "votes"."voter_type" = ? AND "votes"."vote_scope" IS NULL ORDER BY "votes"."id" DESC LIMIT 1 [["votable_id", 10], ["votable_type", "Article"], ["voter_id", 3], ["voter_type", "User"]]
(0.1ms) begin transaction
(0.1ms) commit transaction
Completed 302 Found in 140ms (Views: 0.5ms | ActiveRecord: 84.9ms)
The problem is I am not getting the Completed 302 Found response passed back to my Android application. 问题是我没有将“已完成302找到”响应传递回我的Android应用程序。 It just passes back blank. 它只是传回空白。
Controller: 控制器:
def upvote
@article.upvote_by current_user
if @article.vote_registered?
flash[:success] = "Successfully liked"
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { count: @article.get_upvotes.size } }
end
else
flash[:danger] = "You have already liked this"
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { status: :found }, status: 302 }
end
end
end
Android app that deals with the voting and the String webResponse comes back blank if there is an error. 如果出现错误,则处理投票和String webResponse的Android应用将恢复为空白。 Doesn't matter if it's a 401 unauthorized, 302 found, etc, still comes back blank: 不管是未经授权的401,找到的302等,还是空白:
Thanks very much. 非常感谢。
private class VoteTask extends UrlJsonAsyncTask {
public VoteTask(Context context) {
super(context);
}
@Override
protected JSONObject doInBackground(String... urls) {
DefaultHttpClient webClient = new DefaultHttpClient();
HttpPut put = new HttpPut(urls[0]);
JSONObject holder = new JSONObject();
JSONObject voteObj = new JSONObject();
JSONObject json = new JSONObject();
try {
try {
// setup the returned values in case
// something goes wrong
//json.put("success", false);
// json.put("info", "Something went wrong. Retry!");
//get stored values to prove the user is authorised
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String id = sharedPreferences.getString("userId", "default value");
String authToken = sharedPreferences.getString("AuthToken", "default value");
String email = sharedPreferences.getString("email", "default value");
voteObj.put("votable_id",articleId);
voteObj.put("votable_type", "Article");
voteObj.put("voter_id", id);
voteObj.put("voter_type", "User");
voteObj.put("vote_flag", voteFlag);
voteObj.put("vote_weight", "1");
holder.put("votes", voteObj);
holder.put("article", articleId);
StringEntity se = new StringEntity(holder.toString());
put.setEntity(se);
// setup the request headers
put.setHeader("Accept", "application/json");
put.setHeader("Content-Type", "application/json");
// add email and auth token to validate
put.setHeader("X-User-Email", email);
put.setHeader("X-User-Token", authToken);
//response = webClient.execute(put);
//json = new JSONObject(response);
webResponse = String.valueOf(webClient.execute(put).getStatusLine().getStatusCode());
json = new JSONObject(webResponse);
} catch (HttpResponseException e) {
e.printStackTrace();
Log.e("ClientProtocol", "" + e);
json.put("info", "Email and/or password are invalid. Retry!");
} catch (IOException e) {
e.printStackTrace();
Log.e("IO", "" + e);
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("JSON", "" + e);
}
return json;
}
After days of searching and comparing my code it appears it was 99% working. 经过数天的搜索和比较我的代码,看来它可以正常工作99%。 The one thing I was missing was this: 我缺少的一件事是:
http://guides.rubyonrails.org/layouts_and_rendering.html#the-status-option http://guides.rubyonrails.org/layouts_and_rendering.html#the-status-option
Basically a 302-found response class is marked as redirection so I never got the response back from the server. 基本上,找到302的响应类被标记为重定向,所以我从服务器再也没有得到响应。 I changed the error to a 409-conflict whose response class is client error and I received it back in my webResponse, so if I receive a 409 it means the user has already voted. 我将错误更改为409-conflict,其响应类别为客户端错误,并在我的webResponse中收到了它,因此,如果我收到409,则表明用户已经投票。
def upvote
@article.upvote_by current_user
if @article.vote_registered?
flash[:success] = "Successfully liked"
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { count: @article.get_upvotes.size } }
end
else
flash[:danger] = "You have already liked this"
respond_to do |format|
format.html {redirect_to :back }
format.json { head :conflict }
end
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.