【问题标题】:Return Http error responses to API json向 API json 返回 Http 错误响应
【发布时间】:2016-03-19 00:43:03
【问题描述】:

我的 rails 应用程序可以正常返回 http 200 代码,但如果出现错误,我希望我的控制器将错误传递给 JSON,以便我可以在我的 Android 应用程序中处理它。

如果投票成功,我会在我的 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)

如果不成功(因为该人已经投票),我会得到以下信息:

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)

问题是我没有将 Completed 302 Found 响应传回我的 Android 应用程序。它只是传回空白。

控制器:

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

如果出现错误,处理投票和字符串 webResponse 的 Android 应用会返回空白。不管是未经授权的 401、找到的 302 等等,仍然返回空白:

非常感谢。

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;
        }

【问题讨论】:

    标签: android ruby-on-rails json api


    【解决方案1】:

    经过几天的搜索和比较我的代码,它似乎 99% 都在工作。我缺少的一件事是:

    http://guides.rubyonrails.org/layouts_and_rendering.html#the-status-option

    基本上 302-found 响应类被标记为重定向,所以我从来没有从服务器得到响应。我将错误更改为 409 冲突,其响应类是客户端错误,我在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 2017-04-05
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      相关资源
      最近更新 更多