Błąd podczas pobierania danych z RESPONSE ( Retrofit )

Odpowiedz Nowy wątek
2018-11-17 16:08
0

Cześć ! Mam problem ! Otóż niedawno zacząłem uczyć się używać biblioteki Retrofit ( dotychczas używałem Volley ). Mój JSON jest poprawny ( sprawdzałem go )
Wyskakuje mi taki błąd:

E/MainActivity: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $

JSON:

{
    "statusOfLogin": 1, 
    "id": "2"
}

MainActivity:

public void onClick(View view)
    {
        EditText usernameET = findViewById(R.id.usernameET);
        EditText passwordET = findViewById(R.id.passwordET);

        String username = usernameET.getText().toString();
        String password = passwordET.getText().toString();

        final RequestModel requestModel = new RequestModel();

        requestModel.setUsername(username);
        requestModel.setPassword(password);

        Gson gson = new GsonBuilder()
                .setLenient()
                .create();

        final Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

        WebAPIInterface webAPIInterface = retrofit.create(WebAPIInterface.class);

        webAPIInterface.login(requestModel).enqueue(new Callback<ResponseModel>() {
            @Override
            public void onResponse(Call<ResponseModel> call, Response<ResponseModel> response) {

                if(response.isSuccessful())
                {
                    Log.v(TAG, "Response is successful !!!");
                    Gson gson = new GsonBuilder()
                            .setLenient()
                            .create();

                    gson.fromJson(response.toString(), ResponseModel.class);
                }
                else
                {
                    Log.v(TAG, "Response isn't successful !!!");
                }

            }

            @Override
            public void onFailure(Call<ResponseModel> call, Throwable t) {
                Log.e(TAG, t.toString());
            }
        });
    }

ResponseModel:

public class ResponseModel {

    @SerializedName("statusOfLogin")
    @Expose
    private Integer statusOfLogin;
    @SerializedName("id")
    @Expose
    private Integer id;
    // gettery i settery

RequestModel:

public class RequestModel
{
    @SerializedName("username")
    private String username;

    @SerializedName("password")
    private String password;

WebAPIInterface:

public interface WebAPIInterface
{
    @POST("retrofitLogin.php")
    Call<ResponseModel> login(@Body RequestModel requestModel);
}

Kod PHP po stronie serwera:

<?php
require "connect.php";

$response = array();

$username = $_POST["username"];
$password = $_POST["password"];

$mysql_qry = "SELECT `Haslo` FROM `dane_logowania` WHERE `Login` = '$username'";
$result = mysqli_query($conn ,$mysql_qry);

$data = $result->fetch_array();
if(password_verify($password, $data['Haslo']))
{
     $qry = "SELECT `ID` FROM `dane_logowania` WHERE `Login` = '$username'";
     $res = mysqli_query($conn, $qry);
     $data1 = $res->fetch_array();

     $response["statusOfLogin"] = 1;
     $response["id"] = $data1["ID"];

     echo json_encode($response);

}
else
{
   $response["statusOfLogin"] = 0;
   $response["id"] = 0;

   echo json_encode($response);
}
?>

Jak to naprawić ?
I jeszcze jedno pytanie.
Czy ten POST jest dobrze wykonany ( w sensie czy do skryptu są przekazane dane z klasy RequestModel )?

Pozostało 580 znaków

2018-11-17 16:34
0

A rozumiesz co chcesz zrobić tymi linijkami kodu?

@Override
public void onResponse(Call<ResponseModel> call, Response<ResponseModel> response) {
  if(response.isSuccessful())
  {
    Gson gson = new GsonBuilder()
        .setLenient()
        .create();

    gson.fromJson(response.toString(), ResponseModel.class);
  }
}

Podpowiedź - zobacz jak wygląda response.toString().

edytowany 1x, ostatnio: Michał Sikora, 2018-11-17 16:34
Teraz nie mam dostępu do komputera Ale próbowałem. Response.toString daje Response @(jakieś cyfry) - Adrian098741 2018-11-17 16:43
A z tym rozumieniem to tak średnio :-( - Adrian098741 2018-11-17 16:43
Wytlumaczył byś ? Tylko tak najbardziej prosto jak byś potrafił - Adrian098741 2018-11-17 16:44
Nie wiem który raz z kolei zwracam Ci uwagę, żebyś nie prowadził tematu w komentarzach. - Michał Sikora 2018-11-17 16:49

Pozostało 580 znaków

2018-11-17 16:59
0

Odnośnie pytania w komentarzach - Retrofit zwraca Ci już zdeserializowany obiekt. Po to instaluje się w nim konwerter dla Gsona, żebyś nie musiał sam dbać o mapowanie z JSONa na obiekty i z obiektów na JSONy. Żeby pobrać swój obiekt musisz wywołać response.body().

Poczytaj o tym, czym są typy generyczne, przejrzyj przykłady na Githubie Retrofita. Poza tym Retrofit jest jedną z najpopularnieszych bibliotek, więc powinieneś sam umieć znaleźć takie informacje w Internecie.

edytowany 1x, ostatnio: Michał Sikora, 2018-11-17 17:00

Pozostało 580 znaków

2018-11-17 17:10
0

Jak pobieram dane używając response.body() to pokazuje mi się NullPointerException.
A w sprawie tego gson-a. Czyli muszę mieć w klasach @SerializedName() jako adnotacje czy nie ( oczywiście tylko jak używam retrofit-a )?

Pozostało 580 znaków

2018-11-17 17:17
0

No to nie masz poprawnej odpowiedzi z serwera. Co do @SerializedName, to nie jest to konieczne, jeżeli zmienna nazywa się tak samo jak pole w JSONie i nie obfuskujesz kodu z tymi polami.

Pozostało 580 znaków

2018-11-17 17:29
0

To jaka ma być odpowiedź z serwera. Odpowiedź powinna być poprawna. JSON jest poprawny

Pozostało 580 znaków

2018-11-17 17:40
0

W zasadzie ta którą wkleiłeś, jest poprawna. W każdym razie jest zrozumiała dla Gsona, żeby przekonwertować ją do Twojego obiektu.

{
    "statusOfLogin": 1, 
    "id": "2"
}

Masz problem z szukaniem przyczyn problemów, a co z tym idzie z informowaniem innych, żeby mogli Ci pomóc. Jakby ktoś Ciebie poprosił, żebyś mu wyjaśnił, gdzie ma błąd i powiedział Ci, że leci NullPointerException, to jak byś zareagował? Musisz się nauczyć precyzyjnie wyrażać, jeżeli chcesz być programistą (choć to nie tyczy się tylko tego zawodu).

Wklej kawałek kodu, który powoduje błąd i wrzucaj pełen komunikat a nie tylko jego wyrywek czy typ wyjątku.

edytowany 1x, ostatnio: Michał Sikora, 2018-11-17 17:40

Pozostało 580 znaków

2018-11-17 17:47
0

Ok, dzięki za poradę. Wiem że popełniał jeszcze dużo błędów. Jak by ludzie na tym forum poznali mój prawdziwy wiek to pewnie nie brali by mnie na poważnie.
A kod wkleję jak do domu wrócę

Nie przejmuj się popełnianiem błędów czy wiekiem. Młody każdy był, błędy każdy popełniał. Aczkolwiek to nie są wymówki i moim zdaniem masz problem z przedstawianiem swoich problemów i powinieneś się na tym skupić, jeżeli oczekujesz pomocy od innych. Bo to już nie pierwszy temat, w którym w zasadzie nie da Ci się pomóc ze względu na nieprecyzyjność. Możesz przed wysłaniem wiadomości przeczytać ją na spokojnie pod nosem i zastanowić się, czy są tam informacje, które pozwoliłby drugiej osobie odtworzyć błąd. - Michał Sikora 2018-11-17 17:57
Ja jestem świadomy swoich błędów i nie mam zamiaru się z tym kryć. Tak naprawdę to czasem nie wiem co dodać jako szczegół do postu i może z tego wynikać problem że zrozumieniem o co mi chodzi ( to też nie jest od tego żeby się tłumaczyć) - Adrian098741 2018-11-17 18:00
Zawsze postaraj się wrzucić minimalną ilość kodu, która pozwala odtworzyć błąd i cały komunikat błędu, a nie tylko jedną linijkę, jeżeli akurat leci wyjątek. - Michał Sikora 2018-11-17 18:03
Dzięki za radę - Adrian098741 2018-11-17 18:07

Pozostało 580 znaków

2018-11-18 09:13
0

Popróbowałem ze zmianą kodu i już mniej więcej wiem z czym nie działa.
Skrypt PHP teraz wygląda tak:

<?php
require "connect.php";

if($_SERVER['REQUEST_METHOD'] === 'POST')
{
   $jsonToDecode = file_get_contents('php://input');
   $json = json_decode($jsonToDecode, true);

   $username = $obj['username'];
   $password = $obj['password'];

   $mysql_qry = "SELECT `Haslo` FROM `dane_logowania` WHERE `Login` = '$username'";
   $result = mysqli_query($conn ,$mysql_qry);

   $data = $result->fetch_array();
   if(password_verify($password, $data['Haslo']))
   {
      $qry = "SELECT `ID` FROM `dane_logowania` WHERE `Login` = '$username'";
      $res = mysqli_query($conn, $qry);
      $data1 = $res->fetch_array();

      $resp = array("statusOfLogin" => 1, "id" => $data1["ID"]);

      echo json_encode($resp);

   }
   else
   {
      $resp = array("statusOfLogin" => 0, "id" => 0);

      echo json_encode($resp);
   }
}
else
{
   $response['statusOfLogin'] = 9999;
   $response['id'] = 0;
}

?>

W skrypcie PHP gdy ustawiam zamiast

$username = $obj['username'];
$password = $obj['password'];

to:

$username = "adfgh"; // to samo wysyłam jako login i hasło do skryptu
$password = "adfgh";

to wtedy w LogCat pokazuje mi się odpowiednie ID i odpowiedni STATUS.( takie jakie jest ustawione w bazie MySQL. response.body.toString daje

V/MainActivity: Response is successful !!!
    RESPONSE: [email protected]

Kiedy w kodzie jest to pierwsze ( z $obj ) to wtedy wyrzuca mi błąd ( tylko jedną linijkę ) :

E/MainActivity: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
edytowany 2x, ostatnio: Adrian098741, 2018-11-18 09:16

Pozostało 580 znaków

2018-11-18 14:44
0

Już rozwiązałem mój problem. W interfejsie zamiast @Body użyłem @Field.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0