【问题标题】:Checking username availability by using a request sent to the API (Retrofit)使用发送到 API 的请求检查用户名可用性(改造)
【发布时间】:2021-04-14 06:18:41
【问题描述】:

我正在尝试创建一个简单的应用程序来处理登录和注册过程。 我在验证我的注册表单时遇到问题。我想检查输入的用户名是否可用。我为此创建了一个端点,它返回带有单个值 {"bool" : "true"} 或 {"bool" : "false"} 的 JSON。

我使用以下函数验证提供的数据:

private boolean validateUsername(){
    String val = usernameInput.getEditText().getText().toString().trim();

    checkIfUsernameIsAvailable(val);

    if(val.isEmpty()){
        usernameInput.setError("Field can not be empty");
        return false;
    } else if(val.length() > 20) {
        usernameInput.setError("Username is too large");
        return false;
    } else if(isUsernameInUse) {
        usernameInput.setError("Username is already in use");
        return false;
    } else {
        usernameInput.setError(null);
        usernameInput.setErrorEnabled(false);
        return true;
    }
}

除了检查用户可用性外,一切正常。即:向API发送请求的线程有时会在执行IF之前执行失败。

这是发送请求的方式:

private void checkIfUsernameIsAvailable(String username){
    ExistsUsernameDTO existsUsernameDTO = new ExistsUsernameDTO(username);
    Call<BooleanDTO> call = userService.existsByUsername(existsUsernameDTO);

    call.enqueue(new Callback<BooleanDTO>() {

        @Override
        public void onResponse(Call<BooleanDTO> call, Response<BooleanDTO> response) {
            if (response.isSuccessful()){
                isUsernameInUse = response.body().getBool();
            } else {
                Toast.makeText(RegisterActivity.this, "username_check_failed", Toast.LENGTH_LONG).show();
            }
        }

        @Override
        public void onFailure(Call<BooleanDTO> call, Throwable t) {
            Toast.makeText(RegisterActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
        }
    });
}

这是一个在单击 REGISTER 按钮时启动的函数:

public void callNextRegisterScreen(View view) {

    if (!validateUsername()){
        return;
    }

    Intent intent = new Intent(getApplicationContext(), RegisterUserDetailsActivity.class);

    Pair[] pairs = new Pair[4];
    pairs[0] = new Pair<View, String>(backBtn, "transition_back_arrow_btn");
    pairs[1] = new Pair<View, String>(titleText, "transition_title_text");
    pairs[2] = new Pair<View, String>(nextBtn, "transition_next_btn");
    pairs[3] = new Pair<View, String>(loginBtn, "transition_login_btn");

    ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(RegisterActivity.this, pairs);
    startActivity(intent, activityOptions.toBundle());
}

如何让验证等待查询执行或如何以更好的方式执行此验证?

【问题讨论】:

  • 虽然从逻辑的角度来看我不熟悉 android 开发,但我会说你应该在完成空虚和长度检查后发送此检查。这意味着如果这 2 个检查失败,则无论如何都不需要发送调用。
  • 是的,我希望在空性和长度验证后执行检查功能,但我不知道如何使 checkIfUsernameIsAvailable 函数返回布尔值(这很困难,因为它使用内部类)。此外,在另一个论坛帖子中,人们写道,异步函数应该返回 void,而不是布尔值
  • 我认为 callNextRegisterScreen 应该在 checkIfUsernameIsAvailable 方法成功的情况下触发。

标签: java android rest retrofit


【解决方案1】:

当您的“用户名可用”网络请求返回成功时,您需要导航到下一个屏幕,例如您可以将代码重构如下:

public void callNextRegisterScreen() {
    validateUsername()
}

private void validateUsername(){
    String val = usernameInput.getEditText().getText().toString().trim();

    if(val.isEmpty()){
        usernameInput.setError("Field can not be empty");
        return;
    } else if(val.length() > 20) {
        usernameInput.setError("Username is too large");
        return;
    } else if(isUsernameInUse) {
        usernameInput.setError("Username is already in use");
        return;
    }

    checkIfUsernameIsAvailable(val);
}

private void checkIfUsernameIsAvailable(String username){
    ExistsUsernameDTO existsUsernameDTO = new ExistsUsernameDTO(username);
    Call<BooleanDTO> call = userService.existsByUsername(existsUsernameDTO);

    call.enqueue(new Callback<BooleanDTO>() {

        @Override
        public void onResponse(Call<BooleanDTO> call, Response<BooleanDTO> response) {
            if (response.isSuccessful()){
                isUsernameInUse = response.body().getBool();
                if(isUsernameInUse)
                  Toast.makeText(RegisterActivity.this, "username in use",Toast.LENGTH_LONG).show();
                else
                  navigateNextRegisterScreen()
            } else {
                Toast.makeText(RegisterActivity.this, "username_check_failed", Toast.LENGTH_LONG).show();
            }
        }

        @Override
        public void onFailure(Call<BooleanDTO> call, Throwable t) {
            Toast.makeText(RegisterActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
        }
    });
}


public void navigateNextRegisterScreen(){

    Intent intent = new Intent(getApplicationContext(), RegisterUserDetailsActivity.class);

    Pair[] pairs = new Pair[4];
    pairs[0] = new Pair<View, String>(backBtn, "transition_back_arrow_btn");
    pairs[1] = new Pair<View, String>(titleText, "transition_title_text");
    pairs[2] = new Pair<View, String>(nextBtn, "transition_next_btn");
    pairs[3] = new Pair<View, String>(loginBtn, "transition_login_btn");

    ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(RegisterActivity.this, pairs);
    startActivity(intent, activityOptions.toBundle());
}

【讨论】:

  • 非常感谢!您的解决方案帮助很大;)
  • 非常欢迎您,如果答案对您有帮助,请采纳或投赞成票,以便其他人能够识别问题和解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-24
  • 2018-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
相关资源
最近更新 更多