Użyj JsonReader.setLenient (true), aby zaakceptować zniekształcony kod JSON w ścieżce wiersza 1 kolumny 1 $

105

Co to za błąd? Jak mogę to naprawić? Moja aplikacja działa, ale nie mogę załadować danych. I to jest mój błąd: użyj JsonReader.setLenient (true), aby zaakceptować zniekształcony kod JSON w ścieżce wiersza 1 kolumny 1 $

Oto mój fragment:

public class news extends Fragment {


private RecyclerView recyclerView;
private ArrayList<Deatails> data;
private DataAdapter adapter;
private View myFragmentView;



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    myFragmentView = inflater.inflate(R.layout.news, container, false);
    initViews();
    return myFragmentView;

}


private void initViews() {
    recyclerView = (RecyclerView) myFragmentView.findViewById(R.id.card_recycler_view);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(layoutManager);
    data = new ArrayList<Deatails>();
    adapter = new DataAdapter(getActivity(), data);
    recyclerView.setAdapter(adapter);

    new Thread()
    {
        public void run()
        {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    loadJSON();
                }
            });

        }
    }
    .start();
}

private void loadJSON() {
    if (isNetworkConnected()){

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .retryOnConnectionFailure(true)
                .connectTimeout(15, TimeUnit.SECONDS)
                .build();

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

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.memaraneha.ir/")
                .client(client)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

        RequestInterface request = retrofit.create(RequestInterface.class);
        Call<JSONResponse> call = request.getJSON();
        final ProgressDialog progressDialog = new ProgressDialog(getActivity());
        progressDialog.show();
        call.enqueue(new Callback<JSONResponse>() {
            @Override
            public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
                progressDialog.dismiss();
                JSONResponse jsonResponse = response.body();
                data.addAll(Arrays.asList(jsonResponse.getAndroid()));
                adapter.notifyDataSetChanged();
            }
            @Override
            public void onFailure(Call<JSONResponse> call, Throwable t) {
                progressDialog.dismiss();
                Log.d("Error", t.getMessage());
            }
        });
    }
    else {
        Toast.makeText(getActivity().getApplicationContext(), "Internet is disconnected", Toast.LENGTH_LONG).show();}
}
private boolean isNetworkConnected() {
    ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo ni = cm.getActiveNetworkInfo();
    if (ni == null) {
        // There are no active networks.
        return false;
    } else
        return true;
}
}

RequestInterface:

public interface RequestInterface {

@GET("Erfan/news.php")
Call<JSONResponse> getJSON();
}

za

AKTUALIZACJA

zawsze ten błąd nie dotyczy twojego json, może wynikać z twojego złego żądania, dla lepszej obsługi, najpierw sprawdź swoje żądanie w listonoszu, jeśli otrzymałeś odpowiedź, a następnie porównaj odpowiedź json z twoim modelem, jeśli nic nie jest nie tak, ten błąd pochodzi z twojego złego żądania, może się również zdarzyć, gdy twoja odpowiedź nie jest josn (w niektórych przypadkach odpowiedź może być html)

erfan
źródło
Pokaż wyniki otrzymane odresponse.body()
OneCricketeer,
@ cricket_007 Edytuję moje pytanie i pokazuję wyniki
erfan
Nie prosiłem o obrazy. Prosiłem o wydrukowanie wartości, która może być zwrócona z serwera.
OneCricketeer
1
Jak wypisać wartość w Javie? System.out.println, tak? W Androidzie możesz korzystać z Logklasy, ale to nie ma znaczenia. Nie otrzymujesz danych lub w pobliżu lub w pobliżu występuje błąd JSONResponse jsonResponse = response.body();. Nie wiem, jak naprawić błąd, ponieważ może to być związane z siecią. Powinieneś być w stanie samodzielnie sprawdzić tę wartość.
OneCricketeer
Nie jestem też profesjonalistą, próbuję cię nauczyć, jak debugować dowolną aplikację Java, nic tak naprawdę specyficznego dla Androida
OneCricketeer

Odpowiedzi:

187

Jest to dobrze znany problem i na podstawie tej odpowiedzi możesz dodać setLenient:

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

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

Teraz, jeśli dodasz to do swojej modernizacji , pojawi się kolejny błąd:

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

Jest to kolejny dobrze znany błąd, na który możesz znaleźć odpowiedź tutaj (ten błąd oznacza, że ​​odpowiedź serwera nie jest dobrze sformatowana); Więc zmień odpowiedź serwera, aby coś zwrócić:

{
    android:[
        { ver:"1.5", name:"Cupcace", api:"Api Level 3" }
        ...
    ]
}

Aby uzyskać lepsze zrozumienie, porównaj swoją odpowiedź z interfejsem API Github .

Sugestia : aby dowiedzieć się, co się dzieje z Twoim request/responsedodatkiem HttpLoggingInterceptorpodczas modernizacji .

W oparciu o odpowiedź Twój ServiceHelper wyglądałby tak:

private ServiceHelper() {
        httpClient = new OkHttpClient.Builder();
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        httpClient.interceptors().add(interceptor);
        Retrofit retrofit = createAdapter().build();
        service = retrofit.create(IService.class);
    }

Nie zapomnij również dodać:

compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
Amir
źródło
edytuję wygląd mojego pytania. ale podaj ten sam błąd: użyj JsonReader.setLenient (true), aby zaakceptować zniekształcony kod JSON w ścieżce wiersza 1 kolumny 1 $. dodaj również zdjęcie błędu w pytaniu
erfan
@erfan zobacz edytowaną odpowiedź; Problem jest, ponieważ odpowiedź z serwera jest nie zgodne z prawdą; usuń „wokół nazwy atrybutu i problem zostanie rozwiązany.
Amir
1
{android: [{ver: "1.5", name: "Cupcace", api: "Api Level 3", pic: "pic2.jpg"}]} to jest dokładnie mój plik json, jak przykład z naszego i wciąż ten sam błąd: '(
erfan
{"android": [{"ver": "1.5", "name": "Cupcace", "api": "level3", "pic": "bane.jpg"}]}, napraw w ten sposób
erfan
3
użyj tego, a natychmiast powie ci, dlaczego twój plik
Saik Caskey
11

Również ten problem występuje, gdy typ zawartości odpowiedzi nie jest application/json. W moim przypadku typ treści odpowiedzi był text/htmli miałem ten problem. Zmieniłem to tak, żeby application/jsondziałało.

Ali Gürelli
źródło
6

Wystąpił błąd w zrozumieniu typu zwrotu. Wystarczy dodać nagłówek, a to rozwiąże problem

@Headers("Content-Type: application/json")
Jahanzaib
źródło
1

W moim przypadku ; co rozwiązało mój problem to .....

Być może miałeś taki plik JSON, klucze bez „ podwójnych cudzysłowów ....

{name: "test", telefon: "2324234"}

Wypróbuj więc dowolny internetowy walidator Json, aby upewnić się, że masz odpowiednią składnię ...

Json Validator Online

shareef
źródło
1

Korzystanie z Moshi:

Podczas budowania usługi modernizacji dodaj .asLenient () do MoshiConverterFactory. Nie potrzebujesz ScalarsConverter. Powinien wyglądać mniej więcej tak:

return Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(ENDPOINT)
                .addConverterFactory(MoshiConverterFactory.create().asLenient())
                .build()
                .create(UserService::class.java)
André Ramon
źródło
0

Zmierzyłem się z tym problemem i przeprowadziłem badania i nic nie uzyskałem, więc próbowałem i wreszcie poznałem przyczynę tego problemu. problem z API, upewnij się, że masz dobrą nazwę zmiennej Użyłem $ start_date i to spowodowało problem, więc próbuję $ startdate i działa!

również upewnij się, że wysyłasz wszystkie parametry deklarowane w API, na przykład $ startdate = $ _POST ['startdate']; $ enddate = $ _POST ['enddate'];

musisz przekazać te dwie zmienne z modernizacji.

również jeśli używasz daty w instrukcji SQL, spróbuj umieścić ją wewnątrz '' jak '2017-07-24'

Mam nadzieję, że Ci to pomoże.

Momen Zaqout
źródło
0

Ten problem zaczął się u mnie nagle pojawiać, więc byłem pewien, że może być inny powód. httpKopiąc głęboko, był to prosty problem, w którym użyłem w BaseUrl Retrofit zamiast https. Więc zmieniam to, aby httpsrozwiązać problem za mnie.

Shubhral
źródło
0

Warto również sprawdzić, czy nie ma błędów w zwracanym typie metod interfejsu. Mogę odtworzyć ten problem, mając niezamierzony typ zwrotu, taki jakCall<Call<ResponseBody>>

Rowland Mtetezi
źródło
0

Bardzo łatwo rozwiązałem ten problem po stwierdzeniu, że dzieje się tak, gdy nie wysyłasz odpowiedniego obiektu JSON, po prostu użyłem echo json_encode($arrayName);zamiastprint_r($arrayName); Z moim php api.

Każdy język programowania lub przynajmniej większość języków programowania powinien mieć własną wersję funkcji json_encode()i json_decode().

Jevon
źródło