Parser работает для некоторых ArrayLists, выдает Expected BEGIN_OBJECT, но был STRING для других - PullRequest
0 голосов
/ 07 мая 2019

У меня были проблемы с этим, но я прочитал другие вопросы по переполнению стека и изначально решил проблемы.Теперь я могу отправлять 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. Я не знаю, как узнать больше об этой проблеме, но одна вещьЯ пытался извлечь JSON для ArrayList<Order> orders и попытался разобрать его вручную:

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;
    }

}

Почтовый индекс.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 голосов
/ 08 мая 2019

Так что я думаю, что ваша проблема в следующем:

"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 вам необходимо соблюдать некоторые правила.

  • Всегда помещайте конструктор по умолчанию без аргументов к объектам данных.
  • Постарайтесь сохранить все коллекции с помощью методов получения и установки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...