【问题标题】:Gson: Expected begin_array but was STRING how to control thisGson: 预期 begin_array 但 STRING 如何控制它
【发布时间】:2019-06-12 19:23:24
【问题描述】:

我正在学习如何在休息服务中生成和使用 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: Expected begin_array but was 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;

}

如果您想查看更多代码或我来解释某些内容,请告诉我,感谢您的帮助。

我认为由于 .toString(),错误可能出在方法 generateJSON 中,但是我应该如何处理这种情况?

【问题讨论】:

  • 警告:您使用的是原始类型ListHashMap)。永远不要在新代码中使用它们。
  • 为什么这么糟糕? :o
  • 因为您失去了类型安全性,使您的代码容易出错。 More about the usage of raw types.

标签: java json rest gson


【解决方案1】:

假设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());
}

【讨论】:

  • 嘿,伙计,这听起来像是一个很棒的解决方案,但如果我尝试一下,那么编辑器会告诉我方法 add 需要 (String, JsonElement),我可以在那里做什么?演员表不起作用它说 ArrayList 不能转换为 gson.JsonElement :/
  • 所以JsonArrayJsonElement 的子类。因此,您需要将现有的java.util.List 转换为com.google.gson.JsonArray 的实例。最坏的情况,您可以将List 的每个元素add 转换为新的JsonArraystatic.javadoc.io/com.google.code.gson/gson/2.6.2/com/google/…
  • 看看我刚刚发布的答案兄弟
【解决方案2】:

正如我所怀疑的,错误出在 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,不知道它是如何工作的,但最后让它工作了。

来源:How to parse this JSON String with 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;
}

它也可以,你们决定使用哪一个,非常感谢。

我唯一的问题是,如果元素是一个数组,里面有更多的数组,你会怎么做?

【讨论】:

    【解决方案3】:

    你不需要手动获取那个json值,给你的方法参数添加requestbody注解

    public PruebaJSON prueba(@RequestBody PruebaJSON json){
        System.out.println(json);
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-10
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 2016-09-26
      相关资源
      最近更新 更多