解析 JSON 并在 Listview 中显示检索/获取 URL 服务器“无数据”

Posted

技术标签:

【中文标题】解析 JSON 并在 Listview 中显示检索/获取 URL 服务器“无数据”【英文标题】:Parse JSON And Show In Listview Retrieve/Fetch URL Server " No Data " 【发布时间】:2019-07-26 20:01:33 【问题描述】:

我在 android 中从 JSON 解析到 Listview 时遇到问题。这是来自 JSON 的数据示例:


    "status": 
        "statusCode": 200,
        "success": true,
        "message": "Success"
    ,
    "demandes": [
            "id": "1",
            "dateCreation": "21/01/2014",
            "tagDemand": "xxxxxxxxxxxx",
            "descDemande": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "imageUrl": "https://picsum.photos/3800/50/?image=1"
        ,
        
            "id": "2",
            "dateCreation": "15/01/2017",
            "tagDemand": "yyyyyyyyyyyyyyyyyyyy",
            "descDemande": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
            "imageUrl": "https://picsum.photos/3500/5200/?image=221"
        
    ]

这是主要活动:

public class MyRequests extends AppCompatActivity 

private String jsonURL = "https://26ae7d0d-62b2-4cc4-8ff7-009bee255089.mock.pstmn.io/demands";
private final int jsoncode = 1;
private ListView listView;
ArrayList<DemandeModel> demandeModelArrayList;
private DemandeAdapter demandeAdapter;
String response = "";


private static ProgressDialog mProgressDialog;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my_requests);
    listView = findViewById(R.id.lv);
    fetchJSON();


@SuppressLint("StaticFieldLeak")
private void fetchJSON() 

    showSimpleProgressDialog(this, "Chargement...", "Récupération des données", false);

    new AsyncTask<Void, Void, String>() 
        protected String doInBackground(Void[] params) 
            //  String response="";
            HashMap<String, String> map = new HashMap<>();
            try 
                HttpRequest req = new HttpRequest(jsonURL);
                response = req.prepare(HttpRequest.Method.POST).withData(map).sendAndReadString();
             catch (Exception e) 
                response = e.getMessage();
            
            return response;
        

        protected void onPostExecute(String result) 
            //do something with response
            Log.d("newwwss", result);
            onTaskCompleted(result, jsoncode);
        
    .execute();


public void onTaskCompleted(String response, int serviceCode) 
    Log.d("responsejson", response.toString());
    switch (serviceCode) 
        case jsoncode:
            if (isSuccess(response)) 
                removeSimpleProgressDialog();  //will remove progress dialog
                demandeModelArrayList = getInfo(response);
                demandeAdapter = new DemandeAdapter(this, demandeModelArrayList);
                listView.setAdapter(demandeAdapter);

             else 
                Toast.makeText(MyRequests.this, getErrorCode(response), Toast.LENGTH_SHORT).show();
            
    


public ArrayList<DemandeModel> getInfo(String response) 
    ArrayList<DemandeModel> demandeModelArrayList = new ArrayList<>();
    try 
        JSONObject jsonObject = new JSONObject(response);
        if (jsonObject.getJSONObject("status").optString("success").equals("true")) 

            JSONArray dataArray = jsonObject.getJSONArray("demandes");

            for (int i = 0; i < dataArray.length(); i++) 
                DemandeModel playersModel = new DemandeModel();
                JSONObject dataobj = dataArray.getJSONObject(i);
                playersModel.setId(dataobj.getString("id"));
                playersModel.setDate(dataobj.getString("dateCreation"));
                playersModel.setNom(dataobj.getString("tagDemand"));
                playersModel.setDescription(dataobj.getString("descDemande"));
                playersModel.setImgURL(dataobj.getString("imageUrl"));
                demandeModelArrayList.add(playersModel);

            
        

     catch (JSONException e) 
        e.printStackTrace();
    
    return demandeModelArrayList;



public boolean isSuccess(String response) 

    try 
        JSONObject jsonObject = new JSONObject(response);
        if (jsonObject.getJSONObject("status").optString("success").equals("true")) 
            return true;
         else 

            return false;
        

     catch (JSONException e) 
        e.printStackTrace();
    
    return false;


public String getErrorCode(String response) 

    try 
        JSONObject jsonObject = new JSONObject(response);
        return jsonObject.getJSONObject("status").optString("message");

     catch (JSONException e) 
        e.printStackTrace();
    
    return "No data";


public static void removeSimpleProgressDialog() 
    try 
        if (mProgressDialog != null) 
            if (mProgressDialog.isShowing()) 
                mProgressDialog.dismiss();
                mProgressDialog = null;
            
        
     catch (IllegalArgumentException ie) 
        ie.printStackTrace();

     catch (RuntimeException re) 
        re.printStackTrace();
     catch (Exception e) 
        e.printStackTrace();
    



public static void showSimpleProgressDialog(Context context, String title,
                                            String msg, boolean isCancelable) 
    try 
        if (mProgressDialog == null) 
            mProgressDialog = ProgressDialog.show(context, title, msg);
            mProgressDialog.setCancelable(isCancelable);
        

        if (!mProgressDialog.isShowing()) 
            mProgressDialog.show();
        

     catch (IllegalArgumentException ie) 
        ie.printStackTrace();
     catch (RuntimeException re) 
        re.printStackTrace();
     catch (Exception e) 
        e.printStackTrace();
    

所以,我有一个响应“没有数据”,所以我认为这里有问题“if (isSuccess(response))”

这是我的适配器:

public class DemandeAdapter extends BaseAdapter 

    private Context context;
    private ArrayList<DemandeModel> demandeModelArrayList;

    public DemandeAdapter(Context context, ArrayList<DemandeModel> demandeModelArrayList) 

        this.context = context;
        this.demandeModelArrayList = demandeModelArrayList;
    

    @Override
    public int getViewTypeCount() 
        return getCount();
    
    @Override
    public int getItemViewType(int position) 

        return position;
    

    @Override
    public int getCount() 
        return demandeModelArrayList.size();
    

    @Override
    public Object getItem(int position) 
        return demandeModelArrayList.get(position);
    

    @Override
    public long getItemId(int position) 
        return 0;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        ViewHolder holder;

        if (convertView == null) 
            holder = new ViewHolder();
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.demande, null, true);

            holder.iv = (ImageView) convertView.findViewById(R.id.iv);
            holder.id = (TextView) convertView.findViewById(R.id.id);
            holder.name = (TextView) convertView.findViewById(R.id.name);
            holder.desc = (TextView) convertView.findViewById(R.id.desc);
            holder.date = (TextView) convertView.findViewById(R.id.date);

            convertView.setTag(holder);
        else 
            // the getTag returns the viewHolder object set as a tag to the view
            holder = (ViewHolder)convertView.getTag();
        

        Picasso.get().load(demandeModelArrayList.get(position).getImgURL()).into(holder.iv);
        holder.id.setText("ID : "+demandeModelArrayList.get(position).getId());
        holder.date.setText("Date : "+demandeModelArrayList.get(position).getDate());
        holder.name.setText("Name : "+demandeModelArrayList.get(position).getNom());
        holder.desc.setText("Description : "+demandeModelArrayList.get(position).getDescription());

        return convertView;
    

    private class ViewHolder 

        protected TextView id,name,desc,date;
        protected ImageView iv;
    


这是我的模型:

public class DemandeModel 

    private String id;
    private String nom;
    private String description;
    private String date;
    private String imgURL;


    public DemandeModel() 
    

    public DemandeModel(String id, String nom, String description, String date, String imgURL) 
        this.id = id;
        this.nom = nom;
        this.description = description;
        this.date = date;
        this.imgURL = imgURL;
    

    public String getId() 
        return id;
    

    public void setId(String id) 
        this.id = id;
    

    public String getNom() 
        return nom;
    

    public void setNom(String nom) 
        this.nom = nom;
    

    public String getDescription() 
        return description;
    

    public void setDescription(String description) 
        this.description = description;
    

    public String getDate() 
        return date;
    

    public void setDate(String date) 
        this.date = date;
    

    public String getImgURL() 
        return imgURL;
    

    public void setImgURL(String imgURL) 
        this.imgURL = imgURL;
    

这是 HttpRequest :

public class HttpRequest 
public static enum Method 
    POST, PUT, DELETE, GET;


private URL url;
private HttpURLConnection con;
private OutputStream os;

//After instantiation, when opening connection - IOException can occur
public HttpRequest(URL url) throws IOException 
    this.url = url;
    con = (HttpURLConnection) this.url.openConnection();


//Can be instantiated with String representation of url, force caller to check for IOException which can be thrown
public HttpRequest(String url) throws IOException 
    this(new URL(url));
    Log.d("parameters", url);


/**
 * Sending connection and opening an output stream to server by pre-defined instance variable url
 *
 * @param //isPost boolean - indicates whether this request should be sent in POST method
 * @throws IOException - should be checked by caller
 */
private void prepareAll(Method method) throws IOException 
    con.setDoInput(true);
    con.setRequestMethod(method.name());
    if (method == Method.POST || method == Method.PUT) 
        con.setDoOutput(true);
        os = con.getOutputStream();
    


//prepare request in GET method
//@return HttpRequest this instance -> for chaining method @see line 22
public HttpRequest prepare() throws IOException 
    prepareAll(Method.GET);
    return this;


/**
 * Prepares HttpRequest method with for given method, possible values: HttpRequest.Method.POST,
 * HttpRequest.Method.PUT, HttpRequest.Method.GET & HttpRequest.Method.DELETE
 *
 * @param method HttpRequest.Method - nested enum HttpRequest.Method constant
 * @return HttpRequest this instance -> for chaining method @see line 22
 * @throws IOException - should be checked by caller
 */
public HttpRequest prepare(Method method) throws IOException 
    prepareAll(method);
    return this;


/**
 * Adding request headers (standard format "Key":"Value")
 *
 * @param headers String variadic params in standard format "Key":"Value"
 * @return HttpRequest this instance -> for chaining method @see line 22
 */
public HttpRequest withHeaders(String... headers) 
    for (int i = 0, last = headers.length; i < last; i++) 
        String[] h = headers[i].split("[:]");
        con.setRequestProperty(h[0], h[1]);
    
    return this;


/**
 * Writes query to open stream to server
 *
 * @param query String params in format of key1=v1&key2=v2 to open stream to server
 * @return HttpRequest this instance -> for chaining method @see line 22
 * @throws IOException - should be checked by caller
 */
public HttpRequest withData(String query) throws IOException 
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
    writer.write(query);
    writer.close();
    return this;


/**
 * Builds query on format of key1=v1&key2=v2 from given hashMap structure
 * for map: name=Bubu, age=29 -> builds "name=Bubu&age=29"
 * for map: Iam=Groot -> builds "Iam=Groot"
 *
 * @param params HashMap consists of key-> value pairs to build query from
 * @return HttpRequest this instance -> for chaining method @see line 22
 * @throws IOException - should be checked by caller
 */
public HttpRequest withData(HashMap<String, String> params) throws IOException 
    StringBuilder result = new StringBuilder();
    for (Map.Entry<String, String> entry : params.entrySet()) 
        result.append((result.length() > 0 ? "&" : "") + entry.getKey() + "=" + entry.getValue());//appends: key=value (for first param) OR &key=value(second and more)
        Log.d("parameters", entry.getKey() + "  ===>  " + entry.getValue());
    
    withData(result.toString());
    return this;


//When caller only need to send, and don't need String response from server
public int send() throws IOException 
    return con.getResponseCode(); //return HTTP status code to indicate whether it successfully sent


/**
 * Sending request to the server and pass to caller String as it received in response from server
 *
 * @return String printed from server's response
 * @throws IOException - should be checked by caller
 */
public String sendAndReadString() throws IOException 
    BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
    StringBuilder response = new StringBuilder();
    for (String line; (line = br.readLine()) != null; ) response.append(line + "\n");
    Log.d("ressss", response.toString());
    return response.toString();


/**
 * Sending request to the server and pass to caller its raw contents in bytes as it received from server.
 *
 * @return byte[] from server's response
 * @throws IOException - should be checked by caller
 */
public byte[] sendAndReadBytes() throws IOException 
    byte[] buffer = new byte[8192];
    InputStream is = con.getInputStream();
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    for (int bytesRead; (bytesRead = is.read(buffer)) >= 0; ) output.write(buffer, 0, bytesRead);
    return output.toByteArray();


//JSONObject representation of String response from server
public JSONObject sendAndReadJSON() throws JSONException, IOException 
    return new JSONObject(sendAndReadString());


如果有人可以帮助解决这个问题,那将很高兴

【问题讨论】:

【参考方案1】:

我已经更新了解析方法。检查下面

public ArrayList<DemandeModel> getInfo(String response) 
    ArrayList<DemandeModel> demandeModelArrayList = new ArrayList<>();
    try 
        JSONObject jsonObject = new JSONObject(response);
        if (jsonObject.getJSONObject("status").optString("success").equals("true")) 

            JSONArray dataArray = jsonObject.getJSONArray("demandes");

            for (int i = 0; i < dataArray.length(); i++) 
                DemandeModel playersModel = new DemandeModel();
                JSONObject dataobj = dataArray.getJSONObject(i);
                playersModel.setId(dataobj.getString("id"));
                playersModel.setDate(dataobj.getString("dateCreation"));
                playersModel.setNom(dataobj.getString("tagDemand"));
                playersModel.setDescription(dataobj.getString("descDemande"));
                playersModel.setImgURL(dataobj.getString("imageUrl"));
                demandeModelArrayList.add(playersModel);

            
        

     catch (JSONException e) 
        e.printStackTrace();
    
    return demandeModelArrayList;

EDIT下面的方法更新了一点

public boolean isSuccess(String response) 

    try 
        JSONObject jsonObject = new JSONObject(response);
        if (jsonObject.getJSONObject("status").optString("success").equals("true")) 
            return true;
         else 

            return false;
        

     catch (JSONException e) 
        e.printStackTrace();
    
    return false;

编辑 2

更改下一行

response = req.prepare(HttpRequest.Method.POST).withData(map).sendAndReadString();

response = req.prepare().sendAndReadString();

【讨论】:

评论不用于扩展讨论;这个对话是moved to chat。【参考方案2】:

您似乎在读取错误的数据:

jsonObject.getString("status").equals("true")

您的 json respose 示例中没有“状态”。有“成功”。

【讨论】:

是的,你是对的,我会尝试 if (jsonObject.getJSONObject("status").getString("success").equals("true")) 我没有找到解决办法,你觉得呢?

以上是关于解析 JSON 并在 Listview 中显示检索/获取 URL 服务器“无数据”的主要内容,如果未能解决你的问题,请参考以下文章

如何解析对象内的 JSON 字典

将 JSON 解析为 ListView 友好的输出

解析来自 JSON 服务器的数据时,Android ListView 不显示

如何发送数组列表以解析和检索它并在 UItableView 中显示它?

将数据保存到数据库并在 ListView 中检索

使用 html 链接检索 JSON 对象并在另一个 html 页面上显示 json 数据