[java] “BEGIN_OBJECT가 필요하지만 1 행 1 열에서 STRING이었습니다.”
이 방법이 있습니다.
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 열에서 STRING이었습니다.
답변
JSON 문자열을 보지 않아도 오류 메시지에서 클래스 인스턴스로 구문 분석 할 올바른 구조가 아니라는 것을 알 수 있습니다.
Gson은 JSON 문자열이 객체 여는 중괄호로 시작될 것으로 예상합니다. 예 :
{
그러나 전달한 문자열은 열린 따옴표로 시작합니다.
"
답변
서버의 잘못된 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)
{
//...
답변
Retrofit2에서 매개 변수를 raw로 보내려면 스칼라를 사용해야합니다.
먼저 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 Object
이 맞았을 수도 있지만, 당신이받은 응답은 당신의 유효한 데이터가 아닙니다. 마치 당신이 잘못된 것을 연결할 때처럼 WiFi
, 당신은 구문 분석 할 수없는 이상한 응답 < html>.....< /html>
을 GSON
받을 수 있습니다.
try..catch..
충돌을 피하기 위해이 이상한 응답을 위해 몇 가지를 수행해야 할 수도 있습니다 .
답변
나는 해결책을 공유하기 위해 왔습니다. notbook을 강제로 끊은 후 오류가 발생했습니다. 가능한 해결책 clean preject
.
답변
DATE / DATETIME 등과 같은 DESERIALIZED 개체가 있는지 확인하십시오. JSON을 deserialize하지 않고 직접 보내는 경우이 문제가 발생할 수 있습니다.
답변
내 상황에서는 하나를 제외하고 여러 문자열 매개 변수로 구성된 “모델”이 있습니다 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를 통해 검색하면서 JsonObject로 또는 이리저리 Adapter
변환하려면 어떤 형태가 필요하다는 것을 깨달았습니다 BaseModel
. 모델 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[]
클래스)을Adapter
JSONObject로 /로 변환하는 동안 발생할 때마다 입니다.