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)
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)
在 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?