Я разрабатываю приложение для Android. на самом деле моя база данных находится на локальном хосте. Я разработал свой API с использованием PHP. для страницы входа в Android Studio мне нужно проверить правильность учетных данных пользователя или нет. Я столкнулся с проблемой, когда хочу десериализовать json, полученный от API; проблема не заходит в блок Try! не могли бы вы проверить и написать мне какое решение?
Я проверил, работает ли мой API, и я получаю правильный json; это json из одной из моих попыток входа в систему:
{"status":"success","user_count":1,"user":{"id":"2","username":"yasi","password":"yasi"}}
Я помещаю команду «Журнал» в начале своего класса, чтобы проверить, вызывается ли класс и запускается; он запускается, но игнорирует блок Try и переходит к блоку Catch.
public void jsonToUser (String jsonUser){
String username,password,user_count;
try {
JSONObject jsonObject=new JSONObject(jsonUser);
username = jsonObject.getString("username");
password = jsonObject.getString("password");
user_count=jsonObject.getString("user_count");
if (user_count.equals("1"))
{
if (!username.equals("admin"))
{
Intent intent = new Intent(getActivity(), HomePageActivity.class);
startActivity(intent);
}
else
{
Intent intent = new Intent(getActivity(), AdminHomePageActivity.class);
startActivity(intent);
}
}
else
Toast.makeText(getActivity(),"User not Found",Toast.LENGTH_LONG).show();
}
catch (JSONException e){
Log.d("error",e.getMessage());
}
}
Я ожидаю, что следующее действие будет показано, если я введу правильные учетные данные пользователя.
Прежде всего, я работаю над фрагментом, а не над действием.
во-вторых, это код для вызова моего API в OnCreateView():
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new CheckUserLoginAsync().execute("http://10.0.2.2:80/whereToEatAPI/api/check_user_login_api.php"
,txtUsername.getText().toString()
,txtPassword.getText().toString());
Пожалуйста, вставьте код вызова API и откуда вы вызываете этот jsonToUser()
То, что вы описываете, невозможно. Если он переходит в блок catch, то это означает, что он перешел в блок try, и в этом блоке было выброшено исключение JSONException. Ошибка и трассировка стека исключения скажут вам (и нам), в чем проблема если прочитаешь (напиши).
Чтобы получить более подробную информацию об этом, можно сделать e.printStackTrace(); в блоке catch.




Ваш JSON имеет следующую структуру:
{
"status":"success",
"user_count":1,
"user": {
"id":"2",
"username":"yasi",
"password":"yasi"
}
}
Итак, эта линия
username = jsonObject.getString("username");
не вернет «yasi», как вы, вероятно, ожидаете, потому что «username» — это поле «user», а не объекта верхнего уровня. Он либо выдаст исключение, либо вернет null, и в этом случае код, проверяющий, является ли username «admin», выдаст исключение. В любом случае вы попадете в ловушку.
Просто печатать результат getMessage() при обнаружении исключения обычно не очень хорошая идея, потому что «сообщение» для NullPointerException просто «нулевое». (Не уверен, что это из-за отсутствия сообщения или из-за того, что сообщение на самом деле говорит «null», но эффект тот же.) NPE очень распространены, а «null» редко является полезным сообщением об ошибке, поэтому вы всегда должны напечатайте хотя бы тип исключения, или вызовите printStackTrace, или просто передайте все исключение в логгер, который обычно сделает с ним правильные вещи.
Use Gson for best and optimized code
Add Gson dependency in gradle :
implementation 'com.google.code.gson:gson:2.8.5'
Теперь добавьте в проект два класса моделей.
Логин.класс
public class Login {
@SerializedName("status")
@Expose
private String status;
@SerializedName("user_count")
@Expose
private Integer userCount;
@SerializedName("user")
@Expose
private User user;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getUserCount() {
return userCount;
}
public void setUserCount(Integer userCount) {
this.userCount = userCount;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
и Пользователь.класс
public class User {
@SerializedName("id")
@Expose
private String id;
@SerializedName("username")
@Expose
private String username;
@SerializedName("password")
@Expose
private String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
теперь замените десериализацию json на это
public void jsonToUser (String jsonUser){
String username,password,user_count;
try {
Gson gson = new Gson();
Login login =gson.fromJson(jsonUser, Login.class);
username = login.getUser().getUsername();
user_count = String.valueOf(login.getUserCount());
password = login.getUser().getPassword();
if (user_count.equals("1"))
{
if (!username.equals("admin"))
{
Intent intent = new Intent(getActivity(), HomePageActivity.class);
startActivity(intent);
}
else
{
Intent intent = new Intent(getActivity(), AdminHomePageActivity.class);
startActivity(intent);
}
}
else
Toast.makeText(MainActivity.this,"User not Found",Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.e("error",e.getMessage());
}
}
Это оптимизированный и лучший способ синтаксического анализа json, а не ручной синтаксический анализ.
Оптимизирован для чего?
@WillisBlackburn оптимизирован для анализа ответа от API.
Вы обращаетесь к имени пользователя напрямую, но оно находится в пользовательском объекте. Итак, сначала получите объект пользователя, затем попробуйте получить имя пользователя и другие поля.
JSONObject jsonObject=new JSONObject(jsonUser);
JSONObject jsonObjectUser=jsonObject.getJSONObject("user");
username = jsonObjectUser.getString("username");
password = jsonObjectUser.getString("password");
user_count=jsonObjectUser.getString("user_count");
Вы пытались пройти через отладчик? Какая последняя выполненная строка?