"预计BEGIN_OBJECT,但在第1行第1列STRING"

Cra*_*olf 108 java parsing json gson

我有这个方法:

public static Object parseStringToObject(String json) {
    String Object = json;
    Gson gson = new Gson();
    Object objects = gson.fromJson(object, Object.class);
    parseConfigFromObjectToString(object);
    return objects;
}
Run Code Online (Sandbox Code Playgroud)

我想解析一个JSON:

public static void addObject(String IP, Object addObject) {
    try {
        String json = sendPostRequest("http://" + IP + ":3000/config/add_Object", ConfigJSONParser.parseConfigFromObjectToString(addObject));
        addObject = ConfigJSONParser.parseStringToObject(json);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我收到一条错误消息:

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为BEGIN_OBJECT但在第1行第1列为STRING

bhs*_*cer 151

即使没有看到您的JSON字符串,您也可以从错误消息中判断出它不是正确的结构,无法解析为您的类的实例.

Gson希望你的JSON字符串以对象开始括号开头.例如

{
Run Code Online (Sandbox Code Playgroud)

但是你传递给它的字符串以一个开放的引号开头

"
Run Code Online (Sandbox Code Playgroud)

  • '['表示Json数组的开始而不是Json对象. (9认同)
  • 我知道……但是我们必须做什么才能解析它?? (2认同)
  • 亲爱的@bhspencer,我在android apk中使用retrofit从后端的`Restful EJB web service with jboss EAP 7.1`获取一个简单的json,例如`{"ip":"192.167.1.15"}`。但是我得到“预期 BEGIN_OBJECT 但在第 1 行第 1 列为 STRING”请帮助我...这是我的 Web 服务: @Stateless @Path("/getflashcard") public class GetFlashcard { @Interceptors(Validator.class) @GET @Produces(MediaType.APPLICATION_JSON) public String getFlashcard() { String jsonString = new JSONObject().put("ip", "192.167.1.15").toString(); 返回 json 字符串;} } (2认同)

Kei*_*eiv 17

我最近遇到了类似的问题,并找到了一个有趣的解决方案。基本上我需要将以下嵌套 JSON 字符串反序列化到我的 POJO 中:

"{\"restaurant\":{\"id\":\"abc-012\",\"name\":\"good restaurant\",\"foodType\":\"American\",\"phoneNumber\":\"123-456-7890\",\"currency\":\"USD\",\"website\":\"website.com\",\"location\":{\"address\":{\"street\":\" Good Street\",\"city\":\"Good City\",\"state\":\"CA\",\"country\":\"USA\",\"postalCode\":\"12345\"},\"coordinates\":{\"latitude\":\"00.7904692\",\"longitude\":\"-000.4047208\"}},\"restaurantUser\":{\"firstName\":\"test\",\"lastName\":\"test\",\"email\":\"test@test.com\",\"title\":\"server\",\"phone\":\"0000000000\"}}}"
Run Code Online (Sandbox Code Playgroud)

我最终使用正则表达式删除 JSON 开头和结尾的开引号,然后使用apache.commons unescapeJava()方法对其进行转义。基本上将不干净的 JSON 传递到以下方法中以获取干净的 JSON:

private String removeQuotesAndUnescape(String uncleanJson) {
    String noQuotes = uncleanJson.replaceAll("^\"|\"$", "");

    return StringEscapeUtils.unescapeJava(noQuotes);
}
Run Code Online (Sandbox Code Playgroud)

然后使用 Google GSON 将其解析为我自己的对象:

MyObject myObject = new.Gson().fromJson(this.removeQuotesAndUnescape(uncleanJson));
Run Code Online (Sandbox Code Playgroud)


Jes*_*ell 13

来自服务器的无效JSON应始终是预期的用例.传输过程中有一百万件事可能出错.Gson有点棘手,因为它的错误输出会给你一个问题,你捕获的实际异常将是一个不同的类型.

考虑到所有这些,客户端的正确解决方案是

try
{
  gson.fromJSON(ad, Ad.class);
  //...
}
catch (IllegalStateException | JsonSyntaxException exception)
{
  //...
Run Code Online (Sandbox Code Playgroud)

如果您想知道为什么从服务器收到的JSON是错误的,您可以在异常中查看catch块内部.但即使这是你的问题,也不是客户有责任修复它从互联网接收的JSON.

无论哪种方式,客户都有责任在JSON变坏时决定做什么.两种可能性是拒绝JSON并且什么都不做,并再次尝试.

如果您要再试一次,我强烈建议在try/catch块中设置一个标志,然后在try/catch块之外响应该标志.嵌套的try/catch可能是Gson让我们陷入困境的,我们的堆栈跟踪和异常不匹配.

换句话说,即使我承认它看起来不太优雅,我也会推荐

boolean failed = false;

try
{
  gson.fromJSON(ad, Ad.class);
  //...
}
catch (IllegalStateException | JsonSyntaxException exception)
{
  failed = true;
  //...
}

if (failed)
{
  //...
Run Code Online (Sandbox Code Playgroud)


Raj*_*008 6

在 Retrofit2 中,当您想以原始格式发送参数时,您必须使用标量。

首先在你的gradle中添加这个:

    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    compile 'com.squareup.retrofit2:converter-scalars:2.3.0'

    public interface ApiInterface {

    String URL_BASE = "http://10.157.102.22/rest/";

    @Headers("Content-Type: application/json")
    @POST("login")
    Call<User> getUser(@Body String body);

}
Run Code Online (Sandbox Code Playgroud)

我的 SampleActivity :

   public class SampleActivity extends AppCompatActivity implements Callback<User> {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sample);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ApiInterface.URL_BASE)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        ApiInterface apiInterface = retrofit.create(ApiInterface.class);


        // prepare call in Retrofit 2.0
        try {
            JSONObject paramObject = new JSONObject();
            paramObject.put("email", "sample@gmail.com");
            paramObject.put("pass", "4384984938943");

            Call<User> userCall = apiInterface.getUser(paramObject.toString());
            userCall.enqueue(this);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void onResponse(Call<User> call, Response<User> response) {
    }

    @Override
    public void onFailure(Call<User> call, Throwable t) {
    }
}
Run Code Online (Sandbox Code Playgroud)

参考:[如何在 Retrofit 请求的正文中发布原始的整个 JSON?


小智 5

我是来分享解决方案的。在强迫笔记本挂断后,错误发生在我身上。可能的解决方案clean preject