使用Android的REST API

时间:2015-10-11 07:19:01

标签: android json rest android-volley

我对此很陌生,所以我遵循了以下教程:Android: Consuming a Remote JSON API with Volley

我能够从我的API中获取数据,但我提取的资源有点复杂,而且我不知道如何处理它。

这是我得到的JSON:

{
   "data":[
      {
         "id":"1",
         "image":"http:\/\/lorempixel.com\/600\/600\/technics",
         "user":{
            "data":{
               "id":"667636906616952",
               "first_name":"Lowell",
               "last_name":"Leuschke",
               "email":"Esmeralda.Hessel@hotmail.com",
               "joined":{
                  "date":"2015-10-09 15:03:19",
                  "timezone_type":3,
                  "timezone":"UTC"
               }
            }
         },
         "location":{
            "data":{
               "id":"249795421882013",
               "name":"Wedding planner EV",
               "type":"193705277324704",
               "lat":"42.69649",
               "lng":"23.32601"
            }
         },
         "tags":{
            "data":[

            ]
         },
         "likes":{
            "data":[

            ]
         }
      }
   ]
}

这是Post资源。我获取的方法与教程相同,这里是parse方法:

private List<Post> parse(JSONObject json) throws JSONException {
    ArrayList<Post> records = new ArrayList<>();

    JSONArray jsonPosts = json.getJSONArray("data");

    for (int i = 0; i < jsonPosts.length(); i++) {
        JSONObject jsonPost = jsonPosts.getJSONObject(i);
        String id = jsonPost.getString("id");
        String image = jsonPost.getString("image");

        Gson gson = new Gson();
        final User user = gson.fromJson(jsonPost.getString("user"), User.class);
        final Location location = gson.fromJson(jsonPost.getString("location"), Location.class);
        Integer likes = jsonPost.getJSONObject("likes").getJSONArray("data").length();

        Post record = new Post(id, image, user, location, likes);
        records.add(record);
    }

    return records;
}

以下是我的课程。

User

public class User {

    String id;
    String firstName;
    String lastName;
    String email;
    ApiDate joined;


    public User(String id, String firstName, String lastName, String email, ApiDate joined) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.joined = joined;
    }

    public String getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getEmail() {
        return email;
    }

    public ApiDate getJoined() {
        return joined;
    }

    public String getPictureUrl() {
        return "https://graph.facebook.com/" + this.getId() + "/picture?type=normal";
    }
}

Location

public class Location {
    String id;
    String name;
    String type;
    String lat;
    String lng;

    public Location(String id, String name, String type, String lat, String lng) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.lat = lat;
        this.lng = lng;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getType() {
        return type;
    }

    public String getLat() {
        return lat;
    }

    public String getLng() {
        return lng;
    }
}

Post

import java.util.ArrayList;

public class Post {

    String id;
    String image;
    User user;
    Location location;
    ArrayList<User> tags;
    Integer likes;

    public Post(String id, String image, User user, Location location, Integer likes) {
        this.id = id;
        this.image = image;
        this.user = user;
        this.location = location;
        this.likes = likes;
    }

    public String getId() {
        return id;
    }

    public String getImage() {
        return image;
    }

    public User getUser() {
        return user;
    }

    public Location getLocation() {
        return location;
    }


    public Integer getLikes() {
        return likes;
    }
}

问题是,在此fetch方法中,UserLocation未正确设置。我相信存在错误,但我不知道如何处理这种情况。在此之后,我有PostsAdapter之类的内容:

NetworkImageView profilePicture = (NetworkImageView) convertView.findViewById(R.id.profilePicture);

然后:

profilePicture.setImageUrl(post.getUser().getPictureUrl(), userPictureLoader);

post.getUser().getPictureUrl()似乎是空的。

根据要求:

JsonObjectRequest request = new JsonObjectRequest(
        "http://my.rest.api/api/posts",
        null,
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject jsonObject) {
                try {
                    List<Post> posts = parse(jsonObject);

                    mAdapter.swapPostRecords(posts);
                } catch (JSONException e) {
                    Toast.makeText(getActivity(), "Unable to parse data: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                    Log.d("PH_DEBUG:", "Unable to parse data: " + e.getMessage());
                }
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(getActivity(), "Unable to fetch data: " + volleyError.getMessage(), Toast.LENGTH_SHORT).show();
                Log.d("PH_DEBUG:", "Unable to fetch data: " + volleyError.getMessage());
            }
        });

VolleyApplication.getInstance().getRequestQueue().add(request);

2 个答案:

答案 0 :(得分:0)

有几种方法可以解决它,但我的建议是:

在API方面,当您对变量“image”进行编码时,如果您使用的是php,请尝试将url字符串编码为“urlencode”,以避免在编码JSON时使用“\ /”。

$url_encoded = urlencode($your_url_string);

使用“JSON_UNESCAPED_UNICODE”作为JSON编码的选项:

$my = json_encode($my_data,JSON_UNESCAPED_UNICODE);

结果你很可能在字段“image”中看到类似的内容:

"https%3A%2F%2Fendeavor.org.br%2profile_image.png"

在Android方面,当您收到JSON字符串时,请执行以下操作:

 try {
        myURL_Image_decoded = URLDecoder.decode(my_image_url, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    Log.e("URL DECODE", myURL_Image_decoded);

这可以解决斜线编码“\ /".

的问题

答案 1 :(得分:0)

如评论所述,因为在user内部JSONObject是另一个data JSONObject

因此,您应该使用

final User user = gson.fromJson(jsonPost.getJSONObject("user").getString("data"), User.class);

而不是

final User user = gson.fromJson(jsonPost.getString("user"), User.class);

适用于location的相同逻辑。

P / S:为避免NPE,您还应检查JSON对象以确保它们不为空

希望这有帮助!