【问题标题】:Change status code Rails更改状态代码 Rails
【发布时间】:2016-12-14 22:21:29
【问题描述】:

我的处境非常糟糕。

我在一个带有 Ruby on Rails JSON API 的 Android 应用程序上使用 Volley。

问题是 Volley 存在一个错误,使其无法正确识别状态为 401 的任何内容。基本上,每当出现 401 状态时,NetworkResponse 为 null 并且 VolleyError 的类型为 NoConnectionError。

我已经搜索了很多,唯一的解决方法是返回 403 而不是 Volley 可以正确识别的 401。

如果所有对 403 的响应在 rails 中是 401,我如何更改它们的状态代码?我无法控制所有操作并返回 403,例如在设计预制操作时。

有没有办法在 Rails 中完成响应或其他内容?

【问题讨论】:

  • 如果您无法控制 Rails API 状态代码,请尝试其他解决方案,例如扩展 Request 并覆盖 stackoverflow.com/questions/22948006/… 中所述的 parseNetworkResponse
  • 我这样做了,但是当响应返回 401 时,NetworkResponse 为空。
  • 您可以将 volley 添加为模块并修改 BasicNetwork.java 以返回正确的响应
  • @random 介意告诉我该怎么做吗?

标签: android ruby-on-rails json android-volley http-status-code-401


【解决方案1】:

由于 devise 使用的是warden,您可以创建一个自定义的 failureapp 并设置您想要的 http 状态。

在 lib/custom_failure.rb 中

class CustomFailure < Devise::FailureApp
  def respond
    self.status = 403 
    self.content_type = 'json'
    self.response_body = { error: "Invalid Email or password."}.to_json
  end 
end

在 config/initializers/devise.rb 中

config.warden do |manager|
  manager.failure_app = CustomFailure
end 

在 config/application.rb 中

config.autoload_paths << Rails.root.join('lib')

【讨论】:

  • 我会尝试,但这会成为设计内部其他任何东西的失败响应吗?
【解决方案2】:

401 状态代码可能带有空白响应数据,如果您检查此volley code 第 63-75 行

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

如果 jsonString 为空,它仍会尝试从它创建一个 JSONObject new JSONObject(jsonString),这会引发 JSONException

您可以下载 volley 源代码,将其作为模块导入到您的 android studio 项目中,添加它的依赖项并进行此更正:

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
//          Fix for an error on blank success response
//          return Response.success(new JSONObject(jsonString),
//                    HttpHeaderParser.parseCacheHeaders(response));
            if (!jsonString.trim().contentEquals("")) {
                return Response.success(new JSONObject(jsonString),
                        HttpHeaderParser.parseCacheHeaders(response));
            }
            else {
                return Response.success(new JSONObject(),
                        HttpHeaderParser.parseCacheHeaders(response));
            }
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }
}

要将 Volley 添加到您的项目中 - 克隆 Volley 存储库并将其设置为库项目

  1. 通过在命令行中键入以下内容来克隆存储库:

    git clone https://android.googlesource.com/platform/frameworks/volley

  2. 将下载的源代码作为Create an Android Library 中所述的Android 库模块导入您的应用项目。

如果您不想在导入的库中进行修复,也可以尝试Prase 401 volley error message

【讨论】:

    【解决方案3】:

    我从Ruby on Rails 后端找到了我的问题的解决方案,该解决方案适用于整个应用程序,因为许多控制器也会提供401 而不仅仅是devise

    我通过执行以下操作使用了Rack 中间件:

    app/middleware/unauthorized_to_forbidden.rb

    class   UnauthorizedToForbidden
        def initialize(app)
            @app = app 
        end
    
        def call(env)
            status, headers, response = @app.call(env)
            if(status == 401)
                status = 403
            end
            [status, headers, response]
        end
    end
    

    config/application.rb

    class Application < Rails::Application
        config.middleware.use "UnauthorizedToForbidden"
    end
    

    现在UnauthorizedToForbidden 位于Rack 堆栈的底部,并在响应实际发送给用户之前在最后执行。如果它是401,它基本上会将状态代码更改为403

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-06
      • 1970-01-01
      • 2017-01-28
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      • 1970-01-01
      相关资源
      最近更新 更多