提问者:小点点

“应为BEGIN_OBJECT,但在第1行第1列为字符串”


我有这个方法:

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

但我收到一条错误消息:

jsonSyntaxException:java.lang.IllegalStateException:应为BEGIN_OBJECT,但在第1行第1列为字符串


共3个答案

匿名用户

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

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

{

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

"

匿名用户

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

考虑到所有这些,客户端的正确修复是

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

如果您想知道为什么从服务器收到的JSON是错误的,您可以查看catch块内部的异常。 但是即使这是您的问题,也不是客户端的责任来修复它从Internet接收到的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)
{
  //...

匿名用户

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

首先在您的分级中添加以下内容:

    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?