2017-04-01 141 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

相關問題