解析器适用于某些ArrayLists,抛出Expected BEGIN_OBJECT,但对其他字符串则为STRING

时间:2019-05-07 16:03:17

标签: java json gson

我对此有疑问,但阅读了有关Stack Overflow的其他问题,并初步解决了这些问题。现在,我可以在客户端和服务器之间发送JSON,并在客户端中从该JSON创建对象。但是,我不断遇到一个特定对象的错误:

client.restaurant = gson.fromJson(obj.get("restaurant"), Restaurant.class); // works
client.postcodes = gson.fromJson(obj.get("postcodes"), new TypeToken<ArrayList<Postcode>>(){}.getType()); // works
client.orders = gson.fromJson(obj.get("orders"), new TypeToken<ArrayList<Order>>(){}.getType()); // java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at path $[0].dishes.updateListeners

所有JSON根据https://jsonlint.com有效。我不知道如何找到有关此问题的更多信息,但是我尝试的一件事是我提取了ArrayList<Order> orders的JSON并尝试手动解析它:

JsonObject testOrder = parser.parse("{\n" + 
                        "    \"orders\": [\n" + 
                        "        {\n" + 
                        "            \"user\": {\n" + 
                        "                \"userName\": \"Admin\",\n" + 
                        "                \"password\": \"password\",\n" + 
                        "                \"address\": \"University Road\",\n" + 
                        "                \"postcode\": {\n" + 
                        "                    \"postcodeName\": \"SO17 1BJ\",\n" + 
                        "                    \"latLong\": {\n" + 
                        "                        \"lon\": 0.0,\n" + 
                        "                        \"lat\": 0.0\n" + 
                        "                    },\n" + 
                        "                    \"distance\": 0,\n" + 
                        "                    \"updateListeners\": []\n" + 
                        "                },\n" + 
                        "                \"updateListeners\": []\n" + 
                        "            },\n" + 
                        "            \"dishes\": {\n" + 
                        "                \"Sushi Roll\": 5,\n" + 
                        "                \"Side Rice\": 2\n" + 
                        "            },\n" + 
                        "            \"name\": \"07/05/2019 10:23:08\",\n" + 
                        "            \"updateListeners\": []\n" + 
                        "        }\n" + 
                        "    ]\n" + 
                        "}").getAsJsonObject();
client.orders = gson.fromJson(testOrder, new TypeToken<ArrayList<Order>>(){}.getType()));

但是这也不起作用(错误略有不同-Expected BEGIN_ARRAY but was BEGIN_OBJECT)。

编辑:

Order.java

package comp1206.sushi.common;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

import comp1206.sushi.common.Order;

public class Order extends Model implements Serializable {

    private String status;
    private User user;
    private HashMap<Dish, Number> dishes = new HashMap<Dish, Number>();

    public Order() {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/YYYY HH:mm:ss");  
        LocalDateTime now = LocalDateTime.now();  
        this.name = dtf.format(now);
    }

    public Order(User user) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/YYYY HH:mm:ss");  
        LocalDateTime now = LocalDateTime.now();  
        this.name = dtf.format(now);
        setUser(user);
    }

    public Order(User user, Map<Dish, Number> basket) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/YYYY HH:mm:ss");  
        LocalDateTime now = LocalDateTime.now();  
        this.name = dtf.format(now);
        setUser(user);
        basket.forEach((k,v)->addDishes(k,v));
    }

    public Number getDistance() {
        return 1;
    }

    @Override
    public String getName() {
        return this.name;
    }

    public String getStatus() {
        return status;
    }

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

    public void setUser(User user) {
        this.user = user;
    }

    public User getUser() {
        return this.user;
    }

    public void addDishes(Dish dish, Number quantity) {
        // may need to call notifyUpdate?
        dishes.put(dish, quantity);
    }

    public void editDishes(Dish dish, Number quantity) {
        dishes.replace(dish, quantity);
    }

    public void clearDishes() {
        dishes.clear();
    }

    public Number getCost() {
        int total = 0;
        for (Map.Entry<Dish, Number> entry : dishes.entrySet()) {
            int temptotal1 = (int) entry.getKey().getPrice();
            int temptotal2 = (int) entry.getValue();
            total += (temptotal1*temptotal2);
        }
        return total;
    }

    public Map<Dish, Number> getOrderContents() {
        return dishes;
    }

}

Postcode.java:

package comp1206.sushi.common;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import comp1206.sushi.common.Postcode;

public class Postcode extends Model implements Serializable {

    private static final long serialVersionUID = -2179416792423154920L;

    private String postcodeName;
    private Map<String,Double> latLong;
    private Number distance;

    public Postcode(String code) {
        this.postcodeName = code;
        calculateLatLong();
        this.distance = Integer.valueOf(0);
    }

    public Postcode(String code, Restaurant restaurant) {
        this.postcodeName = code;
        calculateLatLong();
        calculateDistance(restaurant);
    }

    @Override
    public String getName() {
        return this.postcodeName;
    }

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

    public Number getDistance() {
        return this.distance;
    }

    public Map<String,Double> getLatLong() {
        return this.latLong;
    }

    protected void calculateDistance(Restaurant restaurant) {
        //This function needs implementing
        Postcode destination = restaurant.getLocation();
        this.distance = Integer.valueOf(0);
    }

    protected void calculateLatLong() {
        //This function needs implementing
        this.latLong = new HashMap<String,Double>();
        latLong.put("lat", 0d);
        latLong.put("lon", 0d);
        this.distance = new Integer(0);
    }

}

1 个答案:

答案 0 :(得分:0)

所以我认为您的问题出在这里:

"dishes": {  
    "Sushi Roll": 5,
    "Side Rice": 2
}

它尝试调用顺序addDishes(Dish dish, Number quantity)的方法,但失败了,因为它具有"Sushi Roll"而不是代表Dish的整个对象。您需要更新Json而不是字符串,以具有与Dish的构造函数匹配的对象。像这样:

"dishes": {  
    {"name":"Sushi Roll","description":"", "price":0.0, "restockThreshold": 0, "restockAmount":0}: 5,
    {"name":"Side Rice","description":"", "price":0.0, "restockThreshold": 0, "restockAmount":0}: 2
}

通常,在与Json打交道时,您需要遵循一些规则。

  • 始终将不带参数的默认构造函数放置到数据对象中。
  • 尝试使用getter和setter保留所有集合。