web-dev-qa-db-ja.com

Retrofit 2 + Rxjava処理エラー

だから私はログインが問題なく行われたときにすでにJsonからトークンを受け取り、ハッシュを受け取ります

しかし、サーバーからの応答がエラーの場合、Jsonメッセージ({message: "Error:wrong email}"を取得できません。onErrorでは、onのようなモデルクラスではなく、引数としてThrowableしか取得しないためです。

サーバーのonErrorからjsonメッセージを取得するにはどうすればよいですか?

final Observable<TokenResponse> observable = Service.login(userCredentials);
    observable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<TokenResponse>() {
                String error="";

                @Override
                public void onCompleted() {
                    mLoginView.whenLoginSucess();
                }

                @Override
                public void onError(Throwable e) {

                    if (e instanceof HttpException) {
                        HttpException exception = (HttpException) e;
                        Response response = exception.response();
                        Converter<ResponseBody, ErrorFromServer> converter = new GsonConverterFactory()
                                .responseBodyConverter(ErrorFromServer.class, Annotation[0]);
                        ErrorFromServer error = converter.convert(response.errorBody());
                    }

                    mLoginView.errorText(error);

                    e.printStackTrace();

                }

                @Override
                public void onNext(TokenResponse tokenResponse) {


                    SharedPreferences.Editor editor = sharedP.edit();
                    editor.putString("hash", tokenResponse.getToken());
                    editor.commit();

                    //getString return key value "hash" if there is no value, returns null
                    hash = sharedP.getString("hash",null);




                }
            });

TokenResponseコード

public class TokenResponse {
@SerializedName("hash")
@Expose
private String token;

@SerializedName("message")
@Expose
private String message;


public String getMessage() {return message;}


public String getToken() {
    return token;
}

}

12
Diogo Rosa

私は解決策を見つけました、私はレトロフィットを作成するアプリケーションクラスを持っています、そして私はちょうどResponseBodyConverter()を使ってResponseBodyを作成して変換しました

                @Override
                public void onError(Throwable e) {
                    if (e instanceof HttpException) {
                        ResponseBody body = ((HttpException) e).response().errorBody();

                        Converter<ResponseBody, Error> errorConverter =
                            application.getRetrofit().responseBodyConverter(Error.class, new Annotation[0]);
                    // Convert the error body into our Error type.
                        try {
                            Error error = errorConverter.convert(body);
                            Log.i("","ERROR: " + error.message);
                            mLoginView.errorText(error.message);
                        } catch (IOException e1) {
                        e1.printStackTrace();
                        }
                     }



                static class Error{
                String message;
                }

受け取ったJSonは{"error":4041、 "message": "Email not found"}だったので、クラスErrorです。ユーザーにメッセージを表示するだけなので、可変メッセージを作成しました。

12
Diogo Rosa

論理エラー(何らかの理由でログインに失敗した)とアプリケーションエラーが混在しています。ログインに失敗した場合にサーバーがHTTP 200と有効なjsonで応答を送信すると、アプリケーションはonErrorを呼び出しません。

したがって、基本的には、サーバーからの(成功した)応答を確認し、提供されたjsonに基づいて、ログインが成功したかどうかを判断する必要があります。

たとえば、サーバーに到達できない場合、または有効な応答を送信できない場合は、onErrorを呼び出す必要があります。

編集:TokenResponseに何が含まれているのかわかりませんが、成功したかどうかに関係なく、ログインの応答は基本的に同じである必要があります。次に、TokenResponseをチェックして、結果にエラーが含まれているかどうかを確認します。

例としてこの回答を確認してください: https://stackoverflow.com/a/31159671/180538

2
WarrenFaith