2017-04-01 201 views
1

这个错误让我疯狂我尝试使用不同种类的排球请求,如JsonArrayRequestJsonObjectRequest,但没有运气!

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期BEGIN_ARRAY但BEGIN_OBJECT位于第1行第2列路径$


这里的JSON响应链接=>http://www.mocky.io/v2/58df83a80f00005922eaf4e1


这里是我的模型类

public class Order { 


@SerializedName("status") 
@Expose 
private String status; //status 

@SerializedName("total") 
@Expose 
private float price; //total 


@SerializedName("created_at") 
@Expose 
private Date time; 

@SerializedName("line_items") 
@Expose 
public List<ItemsNum> lineItems = new ArrayList<ItemsNum>(); 

@SerializedName("sub_orders") 
@Expose 
public List<OrdersNum> subOrders = new ArrayList<OrdersNum>(); 

@SerializedName("shipping_address") 
@Expose 
public CusAddress cusAdress; 

@SerializedName("customer") 
@Expose 
public Customer customer; 


public Order(Customer customer, String status, float price, String cusPicURL, String firstName, String lastName, Date time, List<ItemsNum> lineItems, List<OrdersNum> subOrders, CusAddress cusAdress) { 
    this.status = status; 
    this.price = price; 
    this.customer = customer; 
    this.time = time; 
    this.lineItems = lineItems; 
    this.subOrders = subOrders; 
    this.cusAdress = cusAdress; 
} 


public Date getTime() { 
    return time; 
} 

public void setTime(Date time) { 
    this.time = time; 
} 

public List<ItemsNum> getLineItems() { 
    return lineItems; 
} 

public void setLineItems(List<ItemsNum> lineItems) { 
    this.lineItems = lineItems; 
} 

public List<OrdersNum> getSubOrders() { 
    return subOrders; 
} 

public void setSubOrders(List<OrdersNum> subOrders) { 
    this.subOrders = subOrders; 
} 



public String getStatus() { 
    return status; 
} 

public void setStatus(String status) { 
    this.status = status; 
} 

public float getPrice() { 
    return price; 
} 

public void setPrice(float price) { 
    this.price = price; 
} 

public CusAddress getCusAdress() { 
    return cusAdress; 
} 

public void setCusAdress(CusAddress cusAdress) { 
    this.cusAdress = cusAdress; 
} 



// //////////// Inner-Classes 


public class Customer { 

    @SerializedName("avatar_url") 
    @Expose 
    private String cusPicURL; //avatar_url 

    @SerializedName("first_name") 
    @Expose 
    private String firstName; //first_name 

    @SerializedName("last_name") 
    @Expose 
    private String lastName; //last_name 

    public String getCusPicURL() { 
     return cusPicURL; 
    } 

    public void setCusPicURL(String cusPicURL) { 
     this.cusPicURL = cusPicURL; 
    } 

    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 
} 

public class CusAddress { 

    public String getAddress() { 
     return address; 
    } 

    public void setAddress(String address) { 
     this.address = address; 
    } 

    public String getCity() { 
     return city; 
    } 

    public void setCity(String city) { 
     this.city = city; 
    } 

    public String getState() { 
     return state; 
    } 

    public void setState(String state) { 
     this.state = state; 
    } 

    public String getCountry() { 
     return country; 
    } 

    public void setCountry(String country) { 
     this.country = country; 
    } 

    @SerializedName("address_1") 
    @Expose 
    public String address; 

    @SerializedName("city") 
    @Expose 
    public String city; 

    @SerializedName("state") 
    @Expose 
    public String state; 

    @SerializedName("country") 
    @Expose 
    public String country; 
} 

public class ItemsNum { 

    @SerializedName("id") 
    @Expose 
    public Integer id; 
} 

public class OrdersNum { 

    @SerializedName("id") 
    @Expose 
    public Integer id; 
} 
} 

我的适配器

public class OrdersDataAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 


public Context context; 
private int num; 
ArrayList<Order> orders; 


public OrdersDataAdapter(ArrayList<Order> orders, Context context) { 
    this.orders = orders; 

    this.context = context; 
} 

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_card, parent, false); 

    return new NewOrderVH(v); 

} 


@Override 
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { 
    final Order order = this.orders.get(position); 
    final NewOrderVH vh1 = (NewOrderVH) holder; 
    vh1.setData(orders.get(position)); 

} 

@Override 
public int getItemCount() { 
    return orders.size(); 
} 


public class NewOrderVH extends RecyclerView.ViewHolder { 


    private ImageView cusPic; 
    private TextView cusName; 
    private TextView CusAdress; 
    private TextView vendorsNum; 
    private TextView itemsNum; 
    private TextView time; 


    public NewOrderVH(View itemView) { 
     super(itemView); 


     orderCard = (CardView) itemView.findViewById(R.id.OrderCard); 
     cusPic = (ImageView) itemView.findViewById(R.id.cusPic); 
     cusName = (TextView) itemView.findViewById(R.id.cusName); 
     CusAdress = (TextView) itemView.findViewById(R.id.CusAdress); 
     vendorsNum = (TextView) itemView.findViewById(R.id.vendorsNum); 
     itemsNum = (TextView) itemView.findViewById(R.id.itemsNum); 
     time = (TextView) itemView.findViewById(R.id.time); 


    } 

    public void setData(final Order data) { 


     cusName.setText(data.customer.getFirstName() + "" + data.customer.getLastName()); 
     Picasso.with(context).load(data.customer.getCusPicURL()).into(cusPic); 
     time.setText(data.getTime().getMinutes()); 
     vendorsNum.setText(data.getSubOrders().size()); 
     itemsNum.setText(data.getLineItems().size()); 
     CusAdress.setText(data.cusAdress.getAddress() + "" + data.cusAdress.getCity() + "" + data.cusAdress.getCountry() + "" + data.cusAdress.getState()); 

    } 


} 

}片段内

请求方法

private void fetchPosts() { 


    requestQueue = Volley.newRequestQueue(getActivity()); 

    StringRequest jRequest = new StringRequest(Request.Method.GET, ENDPOINT, onPostsLoaded, onPostsError); 

    requestQueue.add(jRequest); 

} 


private final Response.Listener<String> onPostsLoaded = new Response.Listener<String>() { 
    @Override 
    public void onResponse(String response) { 

     Gson gson = new Gson(); 
     Type listType = new TypeToken<List<Order>>() {}.getType(); 
     modelData = gson.fromJson(response, listType); 


     adapter = new OrdersDataAdapter((ArrayList<Order>) modelData, getActivity()); 
     recyclerView.setAdapter(adapter); 
     adapter.setMode(Attributes.Mode.Single); 

    } 
}; 

private final Response.ErrorListener onPostsError = new Response.ErrorListener() { 
    @Override 
    public void onErrorResponse(VolleyError error) { 
     Log.e("PostActivity", error.toString()); 
    } 
}; 

回答

1

这里你的问题是orders对象。你不反序列化orders。你能解决这个问题

public class OrderHolder{ 
    private List<Order> orders; 

    public List<Order> getOrders(){ return orders; } 

} 

OrderHolder holder = new Gson().fromJson(response, OrderHolder.class); 
modelData = holder.getOrders(); 

JsonElement jelement = new JsonParser().parse(response); 
JsonObject jobject = jelement.getAsJsonObject(); 
String ordersString = jobject.get("orders").getAsString(); 

Gson gson = new Gson(); 
Type listType = new TypeToken<List<Order>>() {}.getType(); 
modelData = gson.fromJson(ordersString, listType); 
+0

关于第二种方法,我得到这个错误..!? https://m15i.imgup.net/xx7c56.JPG –

+0

第一种方法给我这个===> java.lang.NullPointerException:试图调用虚拟方法'java.util.List ......... $ 2 $ 1OrderHolder.getOrders()'空对象引用 –

+0

我更新第二个解决方案 – mismanc

1

预计BEGIN_ARRAY但路线是BEGIN_OBJECT 1列2路$

这很容易阅读:这意味着你解析类似于列表的东西(因此预计BEGIN_ARRAY[),但给定的JSON文档以BEGIN_OBJECT开头,这是由不匹配的预期类型引起的。它发生在JSON文档的开头。

除了mismancanswer,还有一个第三方式,这需要一个稍微代码(可以提取到的方法虽然),但它并不需要两个包装或类似JsonElement和中间JSON树它的子类(第一种情况可能会消耗更多的内存,第二种情况肯定会消耗更多的内存,因为整个JSON树必须存储在内存中)。

// JsonReader allows to read JSON token stream 
try (final JsonReader jsonReader = new JsonReader(new StringReader(JSON))) { 
    // Just skip the leading `{` 
    jsonReader.beginObject(); 
    // Check if the next property name is what we're expecting 
    final String name = jsonReader.nextName(); 
    if (!name.equals("orders")) { 
     throw new MalformedJsonException("Unexpected: " + name); 
    } 
    // If it's fine, then we: 
    // * are assuming the JsonReader "pointer" is at the property value now 
    // * are asking Gson for the proper type adapter 
    @SuppressWarnings("unchecked") 
    final TypeAdapter<List<Order>> typeAdapter = (TypeAdapter<List<Order>>) gson.getAdapter(TypeToken.get(orderListType)); 
    // Just read the orders 
    final List<Order> orders = typeAdapter.read(jsonReader); 
    System.out.println(orders); 
} 

POJO自动转换器/生成器的JSON模式并不总是创建最佳映射。例如:

  • 两者ItemsNumOrdersNum由相同POJO结构表示,但是它可以是final class Id { @SerializedName("id") final Integer id = null; }
  • 客户avatar_url表示为java.lang.String,但它也可以是java.net.URL

小笔记:不需要创建每次需要反序列化时

  • Gson类的实例。它们完全是线程安全的,可以实例化一次,然后轻松重用。另外,创建并配置其他Gson实例可以被注入到你的代码中。
  • Type使用TypeToken生成的实例可以被视为不可变的值对象,因此也可以缓存到static final字段中。
+0

humm,它没有工作..但经过一些挖掘,我发现问题是有关排球请求类型,我使用StringRequest,但我应该使用JsonObjectRequest,因为响应开始于一个..!我会发布正确的解决方案..! thnx非常为你的帮助:) –

1

这里是正确的答案,我使用错误类型的请求..!

JsonObjectRequest jsObjRequest = new  
    JsonObjectRequest(Request.Method.GET,ENDPOINT,null, 
      new Response.Listener<JSONObject>() { 
       @Override 
       public void onResponse(JSONObject response) { 

        Gson gson = new Gson(); 
        Type listType = new TypeToken<List<Order>>() {}.getType(); 
        try { 

         List<Order> o = new ArrayList<>(); 
         o = gson.fromJson(response.getJSONArray("orders").toString(), listType); 
         if(o != null && !o.isEmpty()){ 

          modelData.addAll(o); 
          adapter.notifyDataSetChanged(); 
         } 

        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 

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

       } 
      }); 

    requestQueue.add(jsObjRequest); 

} 
+0

你能否接受mismanc的[回答](http://stackoverflow.com/a/43156604/166589),因为它确实回答了你在这个答案中发现的问题上没有提及的具体原始问题?谢谢。 –

+0

@LyubomyrShaydariv当然! –

+0

@LyubomyrShaydariv谢谢! – mismanc

相关问题