“预期为BEGIN_OBJECT,但位于第1行第1列的STRING处”


126

我有这种方法:

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

我想解析一个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();
    }
}

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

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为BEGIN_OBJECT,但位于第1行第1列


2
发布您的发布请求返回的JSON字符串。
阿德里安·莱昂哈德

发布您的JSON字符串
bhspencer 2015年

Answers:


163

即使没有看到您的JSON字符串,您也可以从错误消息中得知,它不是要解析为类实例的正确结构。

Gson希望您的JSON字符串以对象打开括号开头。例如

{

但是您传递给它的字符串以开引号开头

"

1
该方法的名称就说明了原因。parseStringToObject建议使用JSON对象,该对象始终以开头{
yshavit 2015年

12
'['表示Json数组而不是Json对象的开始。
bhspencer

我知道那..但是解析该怎么办?
Ajay Mistry'8

@AjayMistry如果没有更多细节,您不清楚要问什么。我建议将您的特定问题发布到一个新问题中,并以您要解析的JSON为例。
bhspencer

1
亲爱的@bhspencer我在android apk中使用了改造,以{"ip":"192.167.1.15"}Restful EJB web service with jboss EAP 7.1后端获得一个简单的json 。但是,我得到“预期BEGIN_OBJECT,但在第1行第1列STRING”请帮助我...这是我的Web服务:@Stateless @Path(“ / getflashcard”)公共类GetFlashcard {@Interceptors(Validator.class)@GET @Produces(MediaType.APPLICATION_JSON)public String getFlashcard(){String jsonString = new JSONObject()。put(“ ip”,“ 192.167.1.15”)。toString(); 返回jsonString; }
侯赛因·阿卡贾尼

17

来自服务器的无效JSON应该始终是预期的用例。在传输过程中,有上百万种错误。Gson有点棘手,因为它的错误输出将给您带来一个问题,并且您捕获的实际异常将具有不同的类型。

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

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

如果您想知道为什么从服务器收到的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)
{
  //...

我要添加,因为这样做是为了简化起见我使用了布尔值。在“现实世界”中,您可能需要测试是否存在字符串,该字符串用于存储在单个try / catch块中收集的异常数据,从本质上将事务历史回放给自己,以便您可以针对是否重试,并在最终决定失败时发送有用的输出。
杰西卡·佩内尔

5

在Retrofit2中,当您想原始发送参数时,必须使用Scalars。

首先将其添加到您的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);

}

我的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) {
    }
}

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


3

也许你JSON Object是对的,但您收到的反应是不是你的,当你连接无效,例如有效data.Just WiFi,你可能会接到一个陌生的响应< html>.....< /html>GSON无法解析。

您可能需要try..catch..对这种奇怪的响应进行一些处理以避免崩溃。



3

确保您具有DESERIALIZED对象(例如DATE / DATETIME等)。如果直接发送JSON而不进行反序列化,则可能导致此问题。


发送前已序列化?
ratzip

@ratzip对不起,我的意思是我们应该为DATE | Object添加一个反序列化器(逻辑)。约会时间。当我想将JsonObject映射到JAVA对象时遇到了这个问题。
拉维·瓦杰

3

在我的情况下,我有一个“模型”,它由几个String参数组成,但一个除外:它是byte array byte[]。一些代码片段:

String response = args[0].toString();
Gson gson = new Gson();
BaseModel responseModel = gson.fromJson(response, BaseModel.class);

上面的最后一行是

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column

被触发。通过搜索SO,我意识到我需要某种形式的AdapterBaseModelJsonObject来回转换。具有混合的String,并byte[]在模型做复杂的事情。显然,Gson不是很喜欢这种情况。

我最后做了一个Adapter确保byte[]将其转换为Base64格式。这是我的Adapter课:

public class ByteArrayToBase64Adapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {

    @Override
    public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return Base64.decode(json.getAsString(), Base64.NO_WRAP);
    }

    @Override
    public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(Base64.encodeToString(src, Base64.NO_WRAP));
    }
}

要将JSONObject转换为模型,我使用了以下方法:

Gson customGson = new GsonBuilder().registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64Adapter()).create();
BaseModel responseModel = customGson.fromJson(response, BaseModel.class);

同样,要将模型转换为JSONObject,我使用了以下命令:

Gson customGson = new GsonBuilder().registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64Adapter()).create();
String responseJSon = customGson.toJson(response);

代码的作用基本上是将想要的对象class/object(在这种情况下,byte[]类)通过AdapterJSONObject来回转换期间的遍历。



0

就我而言,我将JSON对象返回为

{“ data”:“”,“ message”:“成功保存了考勤.. !!!”,“ status”:“成功”}

通过将其更改为解决

{“数据”:{},“消息”:“成功保存了考勤.. !!!”,“状态”:“成功”}

这里的数据是一个子JsonObject,它应该从{而不是“”开始



0

不要忘记先使用Gson()将对象转换为Json

  val fromUserJson = Gson().toJson(notificationRequest.fromUser)

然后,您可以使用这个很棒的库轻松地将其转换回对象

      val fromUser = Gson().fromJson(fromUserJson, User::class.java)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.