更改状态代码Rails

时间:2016-08-09 02:26:38

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

我处境非常糟糕。

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

问题是Volley有一个错误,它无法正确识别任何状态401.基本上,只要有401状态,NetworkResponse为null,VolleyError类型为NoConnectionError。

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

如果在轨道中为401,如何将所有响应的状态代码更改为403?我无法控制所有操作并返回403,例如在设计预制操作中。

有没有办法在rails中完成回复或某事?

3 个答案:

答案 0 :(得分:1)

由于设计正在使用warden,您可以创建自定义失败应用程序并设置所需的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')

答案 1 :(得分:1)

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为空,它仍然会尝试从它new JSONObject(jsonString)创建一个JSONObject,它会抛出一个JSONException

您可以下载凌空源代码,将其作为模块导入到您的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库模块。

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

答案 2 :(得分:0)

我从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堆栈的底部,并在响应实际发送给用户之前在最后执行。它基本上会更改状态代码,如果它是401403