使用存储库模式在 MVP 中捕获响应 return
catch the response return in MVP with repository pattern
我遇到了问题:我一直在创建一个将 return 响应的登录过程。如果登录为真,它会给出这样的响应。
{
"error": false, "message": "Logged In Successfully",
"user": {
"username": "administrator",
"email": "admin@admin.com",
"first_name": "USER",
"last_name": "ADMIN"
},
"menu": [
{
"name": "MENU A",
"module": "menu_a",
"controller": "",
"parent_module": "",
"status": ""
},
{
"name": "MENU B",
"module": "menu_b",
"controller": " ",
"parent_module": "",
"status": ""
}
],
"privilege": [
{
"module": "menu_a"
},
{
"module": "menu_b"
}
]
}
然后当它为假时,它会return这样的响应。
{ "error": true, "message": "Incorrect Login", "user": {
"username": "none",
"email": "none",
"first_name": "none",
"last_name": "none",
"company": "none",
"phone": "none",
"gender": "none",
"place_of_birth": "none",
"date_of_birth": "none",
"religion": "none",
"photo": "none" }, "menu": "none", "privilege": "none" }
这是我的代码:
public interface AppDataSource {
Single<LoginResponse> attemptLogin(Login login);
Single<LoginResponse> saveUserData(LoginResponse response);
}
public class AppRemoteDataSource implements AppDataSource {
private final Retrofit retrofit;
@Inject
public AppRemoteDataSource(@NonNull Retrofit retrofit) {
this.retrofit = retrofit;
}
@Override
public Single<LoginResponse> attemptLogin(Login login) {
return retrofit.create(OmrService.class).loginUser(login);
}
@Override
public Single<Boolean> checkLogin() {
throw new UnsupportedOperationException();
}
}
public class AppLocalDataSource implements AppDataSource {
@NonNull
private final SharedPreferences sharedPreferences;
@NonNull
private final Realm realm;
@Inject
public AppLocalDataSource(@NonNull SharedPreferences sharedPreferences, @NonNull Realm realm) {
this.sharedPreferences = sharedPreferences;
this.realm = realm;
}
@Override
public Single<Boolean> checkLogin() {
return Single.create(s -> {
Boolean stsLogin = sharedPreferences.getBoolean("IS_USER_LOGIN", >false);
s.onSuccess(stsLogin);
});
}
@Override
public Single<LoginResponse> saveUserData(LoginResponse response) {
return Single.create(e -> {
if(!response.isError()) {
savePreference(response.getUser());
saveMenuPrivilege(response.getMenu(), >response.getPrivilege());
}
e.onSuccess(response);
});
}
}
public class AppRepository implements AppDataSource {
@NonNull
private final AppDataSource localDataSource;
@NonNull
private final AppDataSource remoteDataSource;
@Inject
public AppRepository(@NonNull @Local AppDataSource localDataSource,
@NonNull @Remote AppDataSource remoteDataSource) {
this.localDataSource = localDataSource;
this.remoteDataSource = remoteDataSource;
}
@Override
public Single<LoginResponse> attemptLogin(Login login) {
return remoteDataSource.attemptLogin(login)
.compose(RxUtils.applySingleSchedulers())
.flatMap(localDataSource::saveUserData);
}
@Override
public Single<Boolean> checkLogin() {
return localDataSource.checkLogin();
}
}
public class LoginPresenter implements LoginContract.Presenter {
private LoginContract.View view;
private CompositeDisposable compositeDisposable = new CompositeDisposable();
private AppRepository repository;
@Inject
public LoginPresenter(AppRepository repository, LoginContract.View view) {
this.repository = repository;
this.view = view;
}
private void attemptLogin(Login login) {
view.showProgressIndicator(true);
compositeDisposable.add(repository.attemptLogin(login)
.subscribe(
response -> {
if(response.isError()) {
Log.d("CHECK RESPONSE ", response.getMessage());
view.makeSnack(response.getMessage().toString().replace("<p>","").replace("</p>",""));
} else {
view.showProgressIndicator(false);
view.startMainActivity();
}
} , e -> {
Log.d("CHECK RESPONSE ERROR", e.getMessage());
view.makeSnack(e.getMessage().toString());
view.showProgressIndicator(false);
}
));
}
}
问题是,当我测试错误的用户名时,Toast 中显示的响应不是 "Incorrect Login",而是 "com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 268 path $.menu"
我知道登录为假时菜单和权限是空的。但是我如何才能捕捉到响应消息 "Incorrect login"?有没有我需要更改的代码部分?
提前致谢
问题出在您的 privilege
密钥上。
成功后它是一个数组:"privilege": [ { "module": "menu_a" }, { "module": "menu_b" } ]
失败是一个字符串:"privilege":"none"
使其工作的一个简单方法是将 "none"
更改为 []
问题出在您的 JSON 反序列化器(GSON?)中,它显然不能以相同的方式表示字符串和数组。
因此,如果您无法更改服务器响应,您很可能需要创建一个可以为您进行转换的自定义反序列化程序。如何做到这一点取决于用于将 JSON 转换为 Java.
的内容
我遇到了问题:我一直在创建一个将 return 响应的登录过程。如果登录为真,它会给出这样的响应。
{
"error": false, "message": "Logged In Successfully",
"user": {
"username": "administrator",
"email": "admin@admin.com",
"first_name": "USER",
"last_name": "ADMIN"
},
"menu": [
{
"name": "MENU A",
"module": "menu_a",
"controller": "",
"parent_module": "",
"status": ""
},
{
"name": "MENU B",
"module": "menu_b",
"controller": " ",
"parent_module": "",
"status": ""
}
],
"privilege": [
{
"module": "menu_a"
},
{
"module": "menu_b"
}
]
}
然后当它为假时,它会return这样的响应。
{ "error": true, "message": "Incorrect Login", "user": {
"username": "none",
"email": "none",
"first_name": "none",
"last_name": "none",
"company": "none",
"phone": "none",
"gender": "none",
"place_of_birth": "none",
"date_of_birth": "none",
"religion": "none",
"photo": "none" }, "menu": "none", "privilege": "none" }
这是我的代码:
public interface AppDataSource {
Single<LoginResponse> attemptLogin(Login login);
Single<LoginResponse> saveUserData(LoginResponse response);
}
public class AppRemoteDataSource implements AppDataSource {
private final Retrofit retrofit;
@Inject
public AppRemoteDataSource(@NonNull Retrofit retrofit) {
this.retrofit = retrofit;
}
@Override
public Single<LoginResponse> attemptLogin(Login login) {
return retrofit.create(OmrService.class).loginUser(login);
}
@Override
public Single<Boolean> checkLogin() {
throw new UnsupportedOperationException();
}
}
public class AppLocalDataSource implements AppDataSource {
@NonNull
private final SharedPreferences sharedPreferences;
@NonNull
private final Realm realm;
@Inject
public AppLocalDataSource(@NonNull SharedPreferences sharedPreferences, @NonNull Realm realm) {
this.sharedPreferences = sharedPreferences;
this.realm = realm;
}
@Override
public Single<Boolean> checkLogin() {
return Single.create(s -> {
Boolean stsLogin = sharedPreferences.getBoolean("IS_USER_LOGIN", >false);
s.onSuccess(stsLogin);
});
}
@Override
public Single<LoginResponse> saveUserData(LoginResponse response) {
return Single.create(e -> {
if(!response.isError()) {
savePreference(response.getUser());
saveMenuPrivilege(response.getMenu(), >response.getPrivilege());
}
e.onSuccess(response);
});
}
}
public class AppRepository implements AppDataSource {
@NonNull
private final AppDataSource localDataSource;
@NonNull
private final AppDataSource remoteDataSource;
@Inject
public AppRepository(@NonNull @Local AppDataSource localDataSource,
@NonNull @Remote AppDataSource remoteDataSource) {
this.localDataSource = localDataSource;
this.remoteDataSource = remoteDataSource;
}
@Override
public Single<LoginResponse> attemptLogin(Login login) {
return remoteDataSource.attemptLogin(login)
.compose(RxUtils.applySingleSchedulers())
.flatMap(localDataSource::saveUserData);
}
@Override
public Single<Boolean> checkLogin() {
return localDataSource.checkLogin();
}
}
public class LoginPresenter implements LoginContract.Presenter {
private LoginContract.View view;
private CompositeDisposable compositeDisposable = new CompositeDisposable();
private AppRepository repository;
@Inject
public LoginPresenter(AppRepository repository, LoginContract.View view) {
this.repository = repository;
this.view = view;
}
private void attemptLogin(Login login) {
view.showProgressIndicator(true);
compositeDisposable.add(repository.attemptLogin(login)
.subscribe(
response -> {
if(response.isError()) {
Log.d("CHECK RESPONSE ", response.getMessage());
view.makeSnack(response.getMessage().toString().replace("<p>","").replace("</p>",""));
} else {
view.showProgressIndicator(false);
view.startMainActivity();
}
} , e -> {
Log.d("CHECK RESPONSE ERROR", e.getMessage());
view.makeSnack(e.getMessage().toString());
view.showProgressIndicator(false);
}
));
}
}
问题是,当我测试错误的用户名时,Toast 中显示的响应不是 "Incorrect Login",而是 "com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 268 path $.menu"
我知道登录为假时菜单和权限是空的。但是我如何才能捕捉到响应消息 "Incorrect login"?有没有我需要更改的代码部分?
提前致谢
问题出在您的 privilege
密钥上。
成功后它是一个数组:"privilege": [ { "module": "menu_a" }, { "module": "menu_b" } ]
失败是一个字符串:"privilege":"none"
使其工作的一个简单方法是将 "none"
更改为 []
问题出在您的 JSON 反序列化器(GSON?)中,它显然不能以相同的方式表示字符串和数组。
因此,如果您无法更改服务器响应,您很可能需要创建一个可以为您进行转换的自定义反序列化程序。如何做到这一点取决于用于将 JSON 转换为 Java.
的内容