Gson: ожидал begin_array, но STRING как это контролировать - PullRequest
0 голосов
/ 12 июня 2019

Я учусь производить и использовать JSON в службах отдыха, но я хочу хорошо изучить его, поэтому я пробую все возможные варианты объектов, один из них - это объект, имеющий атрибут List, такой как этот класс:

import java.util.List;

public class PruebaJSON {

    private String nombre;
    private List atributos;
    private String descripcion;
    public String getNombre() {
        return nombre;
    }
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
    public List getAtributos() {
        return atributos;
    }
    public void setAtributos(List atributos) {
        this.atributos = atributos;
    }
    public String getDescripcion() {
        return descripcion;
    }
    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }   
}

Тогда все, что я делаю на моем методе службы отдыха, это:

@POST
@Path("/prueba")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public PruebaJSON prueba(String data) {

    try {

        JSONObject json = new JSONObject(data);


        Gson convertir = new GsonBuilder().create();
        PruebaJSON pruebaJson = convertir.fromJson(json.toString(), PruebaJSON.class);

        return pruebaJson;
    } catch (Exception e) {
        System.out.println("error " + e);
        return null;
    }

}

Затем в POSTMAN я передаю это:

{
    "descripcion": "Primera prueba",
    "nombre": "Prueba 1",
    "atributos": [
        "hello",
        "kek",
        "lul"
    ]
}

И все работает нормально, проблема в том,когда я пытаюсь сделать то же самое с помощью Java, например:

List atributos = new ArrayList<>();
atributos.add("hello");
atributos.add("kek");
atributos.add("lul");

System.out.println(bus.prueba("Prueba 1", "Primera Prueba", atributos));

bus.prueba просто выполняет службу, но затем в консоли я получаю эту ошибку:

14:16:56,567 INFO  [stdout] (default task-2) error com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 66 path $.atributos

Я сделалпоиск ошибки и нашел это: Gson: ожидаемый begin_array, но был STRING

Я понимаю ошибку, но каково решение?Я не могу реально контролировать, как JSON создает массив, могу ли я?Это метод prueba в моем клиенте:

public String prueba(String nombre, String descripcion, List atributos) {
        HashMap map = new HashMap<>();

        map.put("nombre", nombre);
        map.put("descripcion", descripcion);
        map.put("atributos", atributos);
        String respuesta = utilidadesRestSeguridad.consumir("prueba", map);
        return respuesta;

    }

В моем клиентском компоненте это метод, который создает JSON:

public static JsonObject generateJSON(HashMap map) throws MalformedURLException {
    JsonObject json = new JsonObject();
    for (Object key : map.keySet()) {
        json.addProperty(key.toString(), map.get(key).toString());
    }

    return json;

}

И вот, ребята, если вы хотите увидеть больше кодаили я, чтобы объяснить что-то, скажи мне, что я ценю любую помощь.

Я думаю, может быть, ошибка в методе generateJSON из-за .toString (), но тогда как мне обработать этот случай?

Ответы [ 3 ]

1 голос
/ 12 июня 2019

Если предположить, что строка utilidadesRestSeguridad.consumir("prueba", map) в конечном итоге вызывает ваш метод generateJSON в нисходящем направлении, то ваша проблема, вероятно, связана с методом generateJSON(), как вы подозреваете. По сути, вы просто добавляете все элементы в виде строк. Если один из элементов вашего map является экземпляром List, то вам нужно вызвать JsonObject#add("atributos", value). Например, вам понадобится что-то вроде следующего кода:

if (map.get(key) instanceof List) {
    json.add(key.toString(), map.get(key);
} else {
    json.addProperty(key.toString(), map.get(key).toString());
}
1 голос
/ 12 июня 2019

Как я и подозревал, ошибка была в методе generateJSON, необходимом для добавления этой проверки, предложенной entpnerd:

public static JsonObject generateJSON(HashMap map) throws MalformedURLException {
    JsonObject json = new JsonObject();

    for (Object key : map.keySet()) {
        if (map.get(key) instanceof List) {
            JsonParser parser = new JsonParser();
            parser.parse((map.get(key).toString()));
            json.add(key.toString(), parser.parse((map.get(key).toString())));
        } else {
            json.addProperty(key.toString(), map.get(key).toString());
        }
    }

    return json;
}

Обратите внимание, что мне пришлось использовать JsonParser, не уверен, как он работает, но наконец, который заставил это работать.

Источник: Как проанализировать эту строку JSON с GSON?

В любом случае, я собираюсь попробовать решение, предлагаемое entpnerd, и опубликовать его тоже.

Вот реализация предложения entpnerd:

public static JsonObject generateJSON(HashMap map) throws MalformedURLException {
    JsonObject json = new JsonObject();

    for (Object key : map.keySet()) {
        if (map.get(key) instanceof List) {
            JsonArray jsonArray = new JsonArray();
            for (Object object : (ArrayList<Object>) map.get(key)) {
                jsonArray.add(object.toString());
            }
            json.add(key.toString(), jsonArray);
        } else {
            json.addProperty(key.toString(), map.get(key).toString());
        }
    }

    return json;
}

это тоже работает, вы, ребята, решаете, какой использовать, большое спасибо.

Мой единственный вопрос: чтоесли бы элемент, являющийся массивом, содержал в себе больше массивов, что бы вы сделали?

0 голосов
/ 12 июня 2019

Вам не нужно получать это значение json вручную, добавьте аннотацию requestbody к параметру вашего метода

public PruebaJSON prueba(@RequestBody PruebaJSON json){
    System.out.println(json);
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...