E/Volley:[354] BasicNetwork.performRequest:Android 中登录功能的意外响应代码 404

E/Volley: [354] BasicNetwork.performRequest: Unexpected response code 404 for Login functionality in Android

我正在尝试使用 Android 中的 volley 创建 HTTP 请求以实现登录功能,但我仍然遇到此错误,我尝试了不同的解决方案,例如以不同的方式更改 getHeaders(我找到的解决方案here in other similar topics) 但 none 对我有用。有什么建议么?我正在将 MVP 与 Interactor 结合使用。

这是我的LoginActivity

public class LoginActivity extends AppCompatActivity implements Contract.LoginView {
private LoginPresenter loginPresenter;
TextInputEditText usernameInput, passwordInput;
Button loginBtn;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    loginPresenter = new LoginPresenter(this, this);
    usernameInput = findViewById(R.id.textInputUsername);
    passwordInput = findViewById(R.id.textInputPassword);
    loginBtn = findViewById(R.id.buttonLogin);

    loginBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String username = usernameInput.getText().toString().trim();
            String password = passwordInput.getText().toString().trim();

            LoginModel loginModel = new LoginModel(username, password);
            loginPresenter.start(loginModel);
        }
    });
}

@Override
public void onSuccesView() {
    Toast.makeText(this, R.string.loginSuccessfully, Toast.LENGTH_SHORT).show();
}

@Override
public void onFailedView(String message) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}

}

这是LoginInteractor.java

public class LoginInteractor {

private Contract.LoginListener loginListener;
LoginPresenter loginPresenter;

public LoginInteractor(LoginPresenter loginPresenter) {
    this.loginPresenter = loginPresenter;
}

public void loginPostRequest(final LoginModel loginModel) {
    RequestQueue requestQueue = Volley.newRequestQueue(loginPresenter.getLoginActivityContext());
    final String urlLogin = "https://ancient-earth-13943.herokuapp.com/api/users/login";
    StringRequest loginStringRequest = new StringRequest(Request.Method.POST, urlLogin, new Response.Listener<String>() {
        @Override
        public void onResponse(String loginResponse) {
            Log.i("LOGINTAG", "Response " + loginResponse.toString());
            parseJsonResponseLogin(loginResponse);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.i("LOGINTAG ", "Error: " + error.networkResponse.statusCode);
        }
    })
    {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> loginParams = new HashMap<String, String>();
            loginParams.put("email", loginModel.getUsername());
            loginParams.put("password", loginModel.getPassword());
            return loginParams;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> pars = new HashMap<String, String>();
            pars.put("Content-Type", "application/x-www-form-urlencoded");
            return pars;
        }
    };
    requestQueue.add(loginStringRequest);
}

public void parseJsonResponseLogin(String jsonStr){
    JSONObject jsonObject = null;
    try {
        jsonObject = new JSONObject(jsonStr);
        if(jsonObject.getString("success").equals("true")){
            jsonObject.getString("token");
            Toast.makeText(loginPresenter.getLoginActivityContext(), "SUCCESS!!", Toast.LENGTH_SHORT).show();
        }
    } catch (JSONException e) {
        Toast.makeText(loginPresenter.getLoginActivityContext(), "FAILED!!", Toast.LENGTH_SHORT).show();
    }
}

}

这是我的LoginPresenter.java

public class LoginPresenter implements Contract.LoginListener {

private Contract.LoginView loginView;
private LoginInteractor loginInteractor = new LoginInteractor(this);
private Context loginActivityContext;
public LoginPresenter(Contract.LoginView lw, Context c) {
    this.loginView = lw;
    this.loginActivityContext = c;
}

public void start(LoginModel loginModel) {
    login(loginModel);
}

public void login(LoginModel loginModel) {
    if (checkLoginError(loginModel)) {
        return;
    }
        loginInteractor.loginPostRequest(loginModel);

}

@Override
public void onSucces() {
    loginView.onSuccesView();
}

@Override
public void onFailed(String message) {
    loginView.onFailedView(message);
}

public Context getLoginActivityContext() {
    return loginActivityContext;
}

private boolean checkLoginError(LoginModel loginModel) {
    String username = loginModel.getUsername();
    String password = loginModel.getPassword();

    if (TextUtils.isEmpty(username) || !Patterns.EMAIL_ADDRESS.matcher(username).matches()) {
        loginView.onFailedView("The username is empty or the email is invalid");
        return true;
    }

    if (TextUtils.isEmpty(password) || password.length() < 2) {
        loginView.onFailedView("The password must have at least 6 characters!");
        return true;
    }
    return false;
}

}

我的浏览器在控制台日志中显示此 url (https://ancient-earth-13943.herokuapp.com/api/users/login) 未找到 (404)。我认为你的代码是正确的。问题出在服务器端。