【问题标题】:Stuck with JSONAPI implementation卡在 JSONAPI 实现中
【发布时间】:2017-10-14 18:00:19
【问题描述】:

所以我正在使用jsonapi.org 的格式,我只是在我的字段中不断得到空值。不知道我做错了什么。

这是我尝试解析的 JSON 的 sn-p(它根本没有包含文件)

    {
  "jsonapi": {
    "version": "1.0"
  },
  "meta": {
    "page": "1",
    "pages": "59",
    "records": "588",
    "records_per_page": "10",
    "keywords": "paint"
  },
  "data": [
    {
      "id": "2619621",
      "type": "TalkThread",
      "attributes": {
        "name": "Cracked paint",
        "created": "Thu Apr 21 2016",
        "thread_view": "121",
        "first_nick": "Rupster"
      },
      "links": {
        "self": "2619621-Cracked-paint"
      },
      "relationships": {
        "posts": {
          "meta": {
            "records": "9"
          },
          "data": [
            {
              "id": "60601161",
              "type": "TalkPost",
              "attributes": {
                "text": "The emulsion I applied on to a wall has cracked.I know I can solve the problem by applying a base...",
                "nick": "Rupster"
              }
            },
            {
              "id": "60619191",
              "type": "TalkPost",
              "attributes": {
                "text": "There was paint on the wall before I painted it. I don't know...",
                "nick": "Rupster"
              }
            },
            {
              "id": "60619901",
              "type": "TalkPost",
              "attributes": {
                "text": "The old paint may well have been silk.  I noticed the same i...",
                "nick": "Rupster"
              }
            }
          ]
        },
        "topic": {
          "data": {
            "id": "2750",
            "type": "Topic",
            "attributes": {
              "name": "Property/DIY"
            },
            "links": {
              "self": "property"
            }
          }
        }
      },
      "site": {
        "name": "site"
      }
    }

我已经构建了一个模型类,但它没有按我的预期工作。

SearchTalkThread.java

import com.gustavofao.jsonapi.Annotations.Type;
import com.gustavofao.jsonapi.Models.Resource;

/**
 * Created by bilalhaider on 15/05/2017.
 */
@Type("TalkThread")
public class SearchTalkThread extends Resource {

    public String name;
    public String created;
    public String thread_view;
    public String first_nick;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCreated() {
        return created;
    }

    public void setCreated(String created) {
        this.created = created;
    }

    public String getThread_view() {
        return thread_view;
    }

    public void setThread_view(String thread_view) {
        this.thread_view = thread_view;
    }

    public String getFirst_nick() {
        return first_nick;
    }

    public void setFirst_nick(String first_nick) {
        this.first_nick = first_nick;
    }


}

现在我正在使用 github 用户的 faogustavo 的 JSONApi 库 (link),但它只是没有计划。我会得到 ID、类型和链接,仅此而已。

我的要求是:

NewGsonRequest.java

import android.support.annotation.Nullable;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.JsonRequest;
import com.google.gson.Gson;
import com.gustavofao.jsonapi.JSONApiConverter;
import com.gustavofao.jsonapi.Models.JSONApiObject;
import com.gustavofao.jsonapi.Models.Resource;
import com.mumsnet.talk.common.Constants;
import com.mumsnet.talk.model.search.SearchTalkThread;
import com.mumsnet.talk.model.search.TalkPost;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
/**
 * Created by bilalhaider on 08/05/2017.
 */

public class NewGsonRequest<T> extends JsonRequest<T> {

    private final Gson gson = new Gson();
    private Map<String, String> bodyJson;
    private final Class<T> clazz;
    private Map<String, String> headers;
    private Response.Listener listener;
    private static final String CONTENT_TYPE =
            String.format("application/x-www-form-urlencoded");
    ;

    public NewGsonRequest(String url, Class<T> clazz, Map<String, String> headers, int method, @Nullable Map<String, String> bodyJson,
                          Response.Listener<T> listener, Response.ErrorListener errorListener) {

        super(method, url, getFormDataString(bodyJson), listener, errorListener);
        this.clazz = clazz;
        this.listener = listener;
        this.bodyJson = bodyJson;

        if (headers == null) {
            this.headers = new HashMap<>();
        } else {
            this.headers = headers;
        }

        this.headers.put("client-id", Constants.API_CLIENT_ID);
        this.headers.put("client_secret", Constants.API_CLIENT_SECRET);
//        this.headers.put(CONTENT_TYPE, "application/json; charset=utf-8");
        this.headers.put("Accept-Encoding", "gzip, deflate, sdch");
    }

    private static String getFormDataString(Map<String, String> formData) {

        StringBuilder params = new StringBuilder();
        if (formData != null) {
            for (String key : formData.keySet()) {
                params.append("&").append(key).append("=").append(formData.get(key));
            }

            return params.toString().substring(1);
        } else {
            return null;
        }
    }

    @Override
    public Map<String, String> getParams() throws AuthFailureError {
        return bodyJson != null ? bodyJson : super.getParams();
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return headers != null ? headers : super.getHeaders();
    }

    @Override
    public String getBodyContentType() {
        return CONTENT_TYPE;
    }

    @Override
    protected void deliverResponse(T response) {
        listener.onResponse(response);
    }

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {

        JSONApiConverter api = new JSONApiConverter(SearchTalkThread.class, TalkPost.class);
        JSONApiObject object = new JSONApiObject();


        String json = null;
        String encoding = response.headers.get("Content-Encoding");

        if (encoding != null && encoding.equals("gzip")) {
            json = unpackData(response.data);
            object = api.fromJson(json);
        } else {
            try {
                json = new String(
                        response.data, HttpHeaderParser.parseCharset(response.headers));
                object = api.fromJson(json);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        if (object.getData().size() > 0) {
            if (object.getData().size() == 1) {
                SearchTalkThread searchTalkThread = (SearchTalkThread) object.getData(0);
            } else {
                List<Resource> resources = object.getData();
            }
        }

        return Response.success(gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
    }

    private String unpackData(byte[] data) {
        String output = "";

        try {
            GZIPInputStream gStream = new GZIPInputStream(new ByteArrayInputStream(data));
            InputStreamReader reader = new InputStreamReader(gStream);
            BufferedReader in = new BufferedReader(reader);
            String read;
            while ((read = in.readLine()) != null) {
                output += read;
            }
            reader.close();
            in.close();
            gStream.close();
        } catch (IOException e) {
            return null;
        }

        return output;
    }
}

谁能帮我知道我需要去哪里或我需要做什么?几天来一直让我感到压力,我只是不知道我做错了什么!

EDIT 添加了用于获取 JSON 的附加类。我遇到的问题是在获取数据后对其进行解析。

SearchFeedDataFactory.java

import android.content.Context;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.mumsnet.talk.common.Constants;
import com.mumsnet.talk.request.GsonRequest;
import com.mumsnet.talk.request.NewGsonRequest;
import com.mumsnet.talk.response.SearchResponse;
import com.mumsnet.talk.utils.PreferenceConnector;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by bilalhaider on 03/05/2017.
 */

public class SearchFeedDataFactory {

    private Context mContext;

    public SearchFeedDataFactory(Context context) {
        mContext = context;
    }

    public void searchThreads(String keywords, SearchFeedCallback callback) {

        Map<String, String> accessHeader = new HashMap<>();
        accessHeader.put("Authorization", "Bearer "
                + PreferenceConnector.readString(mContext, "authToken"));

        String searchURL = Constants.BASE_URL + "api/v1/forums/threads/search?keywords=" + keywords
                +"&page=1&per_page=25";

        final SearchFeedCallback searchFeedCallback = callback;

        NewGsonRequest<SearchResponse> searchRequest = new NewGsonRequest<>(searchURL, SearchResponse.class,
                accessHeader, Request.Method.GET, null, new Response.Listener<SearchResponse>() {
            @Override
            public void onResponse(SearchResponse response) {

                searchFeedCallback.onSearchDataReceived(response);

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

                searchFeedCallback.onSearchDataFailed(error);

            }
        });

        RequestFactory.getInstance(mContext).addtoRequestQueue(searchRequest);

    }

    public interface SearchFeedCallback {
        void onSearchDataReceived(SearchResponse response);
        void onSearchDataFailed(Exception exception);
    }


}

SearchResponse.java

import com.google.gson.annotations.SerializedName;
import com.mumsnet.talk.model.search.SearchTalkThread;

import java.util.ArrayList;

/**
 * Created by bilalhaider on 03/05/2017.
 */
public class SearchResponse {

    @SerializedName("data")
    public ArrayList<SearchTalkThread> searchDataList;

    public SearchResponse() {
        searchDataList = new ArrayList<>();
    }

    public SearchTalkThread getItem(int index) {
        return searchDataList.size() - 1 >= index ? searchDataList.get(index) : null;
    }

    public ArrayList<SearchTalkThread> getItems() {
        return searchDataList;
    }

}

提前致谢

【问题讨论】:

  • 你真的调试过代码吗?使用简单的curl 实用程序来验证 JSON 结果的正确性。 FWIW,由于使用在线验证器,JSON 不完整。

标签: android json json-api


【解决方案1】:

不要使用 api.fromJson 尝试下面的代码来解析 Json。

public static final String JSON_ARRAY = "data";
public static final String KEY_ID = "id";
public static final String KEY_NAME = "name";
public static final String KEY_EMAIL = "link";

protected void parseJSON(){
    JSONObject jsonObject=null;
    try {
        jsonObject = new JSONObject(json);
        users = jsonObject.getJSONArray(JSON_ARRAY);

        ids = new String[users.length()];
        names = new String[users.length()];
        emails = new String[users.length()];

        for(int i=0;i<users.length();i++){
            JSONObject jo = users.getJSONObject(i);
            ids[i] = jo.getString(KEY_ID);
            names[i] = jo.getString(KEY_NAME);
            emails[i] = jo.getString(KEY_EMAIL);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

只需检查您是否获得了价值。

【讨论】:

  • 我得到了一些价值。它将我的 JSONObject 拆分为 3 个nameValuePairsjsonapimetadata。仍然没有解析成正确的模型。然后我写错了吗?
  • 不,你没有写错。您正在使用上面编写的 parseJson 函数获取一些值,对吗?现在做一件事创建一个 JsonArray js = new JsonArray(users.getJSONArray("data")) 。在这里你会得到你想要的整个数组。一旦你得到了,你需要得到上面代码中提到的解析对象。
  • 好的,我想我明白了。抱歉,我只是这个新的 JSON 格式的菜鸟
  • 我可以把JSONArray 放在我的parseJson 函数中吗?我收到此错误type org.json.JSONObject cannot be converted to JSONArray users 是 JSON 数组的类型,对吗?抱歉,这太令人困惑了
  • 一步一步来。首先打印您在 parseNetworkResponse 中得到的内容。之后调用 parseJson 并使用您在 parseNetworkResponse 中获得的 json。然后检查你在用户 JsonArray 中得到了什么并打印它的长度。 parseJson 可以正常工作。
【解决方案2】:

您尝试获取的数据是动态的(来自 web 服务)还是静态的(项目中包含的 json 文件)?

我已经浏览了您为 JSONAPI 提供的链接,在该代码中有 MainActivity,其中有用于获取数据的代码,您可以添加相同的代码吗?

【讨论】:

  • 它是动态的。将添加我如何得到它。它可以很好地获取 JSON,但我无法解析它。
  • 你在 NewGsonRequest 的对象中得到了什么?对吗?
  • 我正在获取所需的整个 Json。当它被解析时,我得到的只是idtype 和一个link 属性。没有其他内容被解析。
猜你喜欢
  • 2020-06-06
  • 2021-02-19
  • 2015-12-10
  • 2018-12-17
  • 2013-03-14
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
  • 2018-11-10
相关资源
最近更新 更多