ใช้ JsonReader.setLenient (true) เพื่อยอมรับ JSON ที่ผิดรูปแบบที่บรรทัด 1 คอลัมน์ 1 เส้นทาง $


111

ข้อผิดพลาดนี้คืออะไร? ฉันจะแก้ไขปัญหานี้ได้อย่างไร? แอปของฉันกำลังทำงาน แต่ไม่สามารถโหลดข้อมูลได้ และนี่คือข้อผิดพลาดของฉัน: ใช้ JsonReader.setLenient (true) เพื่อยอมรับ JSON ที่ผิดรูปแบบที่บรรทัด 1 คอลัมน์ 1 เส้นทาง $

นี่คือส่วนของฉัน:

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;
}
}

คำขออินเทอร์เฟซ:

public interface RequestInterface {

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

ก

อัปเดต (อ่านข้อความด้านล่างและค้นหาปัญหาของคุณ)

  • ข้อผิดพลาดนี้ไม่เกี่ยวกับ json ของคุณเสมอมันอาจมาจากคำขอที่ไม่ถูกต้องของคุณเพื่อให้จัดการได้ดีขึ้นก่อนตรวจสอบคำขอของคุณในบุรุษไปรษณีย์หากคุณได้รับการตอบสนองจากนั้นเปรียบเทียบการตอบสนอง json ของคุณกับโมเดลของคุณหากไม่มีอะไรผิดพลาดข้อผิดพลาดนี้มาจากคำขอที่ไม่ถูกต้องของคุณ นอกจากนี้ยังอาจเกิดขึ้นเมื่อการตอบกลับของคุณไม่ใช่ josn (ในบางกรณีการตอบกลับอาจเป็น html)

โปรดแสดงผลลัพธ์ที่คุณได้รับจากresponse.body()
OneCricketeer

@ cricket_007 ฉันแก้ไขคำถามและแสดงผลลัพธ์ของฉัน
erfan

ผมไม่ได้ขอภาพ ฉันขอให้คุณพิมพ์ค่าที่อาจส่งคืนจากเซิร์ฟเวอร์
OneCricketeer

1
คุณพิมพ์ค่าใน Java ได้อย่างไร? System.out.println, ครับ? ใน Android คุณสามารถใช้Logคลาสนี้ได้ แต่ไม่สำคัญ JSONResponse jsonResponse = response.body();คุณไม่ได้รับข้อมูลหรือข้อผิดพลาดที่เกิดขึ้นในหรือรอบ ๆ ฉันไม่รู้วิธีแก้ไขข้อผิดพลาดของคุณเนื่องจากอาจเกี่ยวข้องกับเครือข่าย คุณควรจะตรวจสอบค่านั้นได้ด้วยตัวคุณเอง
OneCricketeer

ฉันก็ไม่ใช่มือโปรเหมือนกันฉันพยายามสอนวิธีแก้จุดบกพร่องของแอปพลิเคชัน Java โดยไม่มีอะไรเฉพาะเจาะจงสำหรับ Android เลย
OneCricketeer

คำตอบ:


200

นี่เป็นปัญหาที่ทราบกันดีและจากคำตอบนี้คุณสามารถเพิ่มsetLenient:

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

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

ตอนนี้หากคุณเพิ่มสิ่งนี้ลงในชุดติดตั้งเพิ่มเติมจะทำให้คุณมีข้อผิดพลาดอื่น:

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

นี่เป็นอีกหนึ่งข้อผิดพลาดที่ทราบกันดีซึ่งคุณสามารถหาคำตอบได้ที่นี่ (ข้อผิดพลาดนี้หมายความว่าการตอบสนองของเซิร์ฟเวอร์ของคุณไม่ได้รับการจัดรูปแบบที่ดี) ดังนั้นเปลี่ยนการตอบสนองของเซิร์ฟเวอร์เพื่อส่งคืนบางสิ่ง:

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

เพื่อความเข้าใจที่ดีขึ้นเปรียบเทียบการตอบสนองของคุณกับGithub API

ข้อเสนอแนะ : เพื่อหาสิ่งที่เกิดขึ้นที่คุณrequest/responseเพิ่มHttpLoggingInterceptorในของคุณติดตั้งเพิ่มเติม

จากคำตอบนี้ServiceHelperของคุณจะเป็น:

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);
    }

อย่าลืมเพิ่ม:

compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'

ฉันแก้ไขรูปลักษณ์คำถามของฉัน แต่ให้ข้อผิดพลาดเดียวกัน: ใช้ JsonReader.setLenient (true) เพื่อยอมรับ JSON ที่ผิดรูปแบบที่บรรทัด 1 คอลัมน์ 1 เส้นทาง $ ยังเพิ่มรูปภาพข้อผิดพลาดในคำถาม
erfan

@erfan ดูคำตอบที่แก้ไข; ปัญหาเกิดจากการตอบกลับของคุณจากเซิร์ฟเวอร์ไม่ถูกต้อง ลบ "รอบชื่อแอตทริบิวต์และปัญหาจะได้รับการแก้ไข
Amir

1
{android: [{ver: "1.5", name: "Cupcace", api: "Api Level 3", pic: "pic2.jpg"}]} นี่คือ json ของฉันเหมือนกับตัวอย่าง ur และยังมีข้อผิดพลาดเดียวกัน: '(
erfan

{"android": [{"ver": "1.5", "name": "Cupcace", "api": "level3", "pic": "bane.jpg"}]} แก้ไขด้วยวิธีนี้
erfan

3
ใช้สิ่งนี้แล้วมันจะบอกคุณทันทีว่าทำไม json ของคุณถึงผิดjsonlint.com
Saik Caskey

11

นอกจากนี้ยังมีปัญหานี้ occurres เมื่อ contenttype application/jsonการตอบสนองไม่ได้ ในประเภทเนื้อหาการตอบกลับกรณีของฉันคือtext/htmlและฉันประสบปัญหานี้ ฉันเปลี่ยนเป็นapplication/jsonแล้วมันใช้งานได้


6

เกิดข้อผิดพลาดในการทำความเข้าใจประเภทการส่งคืนเพียงแค่เพิ่มส่วนหัวและจะแก้ปัญหาของคุณได้

@Headers("Content-Type: application/json")


1

ในกรณีของฉัน; สิ่งที่แก้ปัญหาของฉันคือ .....

คุณอาจมี json แบบนี้คีย์ที่ไม่มี " ใบเสนอราคาคู่ ....

{ชื่อ: "test", โทรศัพท์: "2324234"}

ดังนั้นลองใช้ Json Validator ออนไลน์เพื่อให้แน่ใจว่าคุณมีไวยากรณ์ที่ถูกต้อง ...

Json Validator ออนไลน์


1

การใช้ Moshi:

เมื่อสร้าง Retrofit Service ให้เพิ่ม. asLenient () ไปยัง MoshiConverterFactory ของคุณ คุณไม่จำเป็นต้องมี ScalarsConverter ควรมีลักษณะดังนี้:

return Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(ENDPOINT)
                .addConverterFactory(MoshiConverterFactory.create().asLenient())
                .build()
                .create(UserService::class.java)

0

ฉันประสบปัญหานี้และฉันได้ทำการค้นคว้าและไม่ได้อะไรเลยฉันจึงพยายามและในที่สุดฉันก็รู้สาเหตุของปัญหานี้ ปัญหาใน API ตรวจสอบให้แน่ใจว่าคุณมีชื่อตัวแปรที่ดีที่ฉันใช้ $ start_date และมันทำให้เกิดปัญหาดังนั้นฉันจึงลอง $ startdate และมันก็ใช้ได้!

และตรวจสอบให้แน่ใจว่าคุณได้ส่งพารามิเตอร์ทั้งหมดที่ประกาศบน API เช่น $ startdate = $ _POST ['startdate']; $ enddate = $ _POST ['enddate'];

คุณต้องส่งสองตัวแปรนี้จากชุดติดตั้งเพิ่ม

เช่นกันถ้าคุณใช้วันที่ในคำสั่ง SQL ให้ลองใส่ไว้ใน '' like '2017-07-24'

ฉันหวังว่ามันจะช่วยคุณได้


0

ปัญหานี้เริ่มเกิดขึ้นกับฉันในทันทีดังนั้นฉันจึงแน่ใจว่าอาจมีสาเหตุอื่น เมื่อวันที่ขุดลึกมันเป็นปัญหาง่ายๆที่ผมใช้httpใน BaseUrl ของ Retrofit httpsแทน ดังนั้นการเปลี่ยนมันเพื่อhttpsแก้ปัญหาให้ฉัน


0

สิ่งที่ควรตรวจสอบคือหากมีข้อผิดพลาดใด ๆ ในประเภทการส่งคืนของวิธีการอินเทอร์เฟซของคุณ ฉันสามารถสร้างปัญหานี้ซ้ำได้โดยมีประเภทการส่งคืนโดยไม่ได้ตั้งใจเช่นCall<Call<ResponseBody>>


0

ฉันแก้ไขปัญหานี้ได้อย่างง่ายดายมากหลังจากพบว่าสิ่งนี้เกิดขึ้นเมื่อคุณไม่ได้ส่งออกวัตถุ JSON ที่เหมาะสมฉันใช้สิ่งนี้echo json_encode($arrayName);แทนprint_r($arrayName);ด้วย php api ของฉัน

ภาษาโปรแกรมทุกภาษาหรืออย่างน้อยภาษาโปรแกรมส่วนใหญ่ควรมีเวอร์ชันjson_encode()และjson_decode()ฟังก์ชันของตัวเอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.