"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을 클릭합니다.Json Syntax Exception: java.lang.InlawalStateException:BEGIN_OBJECT가 필요한데 1행 1열에 STRING이었습니다.
JSON 문자열이 표시되지 않더라도 오류 메시지에서 클래스의 인스턴스로 구문 분석되는 구조가 올바르지 않음을 알 수 있습니다.
Gson은 JSON 문자열이 오브젝트 열기 괄호로 시작되어야 합니다.
{
그러나 전달한 문자열은 따옴표로 시작합니다.
"
서버의 잘못된 JSON은 항상 예상된 사용 사례여야 합니다.전염되는 동안 수백만 가지 일이 잘못될 수 있습니다.Gson은 에러 출력으로 인해1가지 문제가 발생하고 실제로 검출되는 예외는 다른 타입이기 때문에 조금 까다롭습니다.
이 모든 것을 염두에 두고, 클라이언트측의 적절한 수정은,
try
{
gson.fromJSON(ad, Ad.class);
//...
}
catch (IllegalStateException | JsonSyntaxException exception)
{
//...
서버로부터 수신한 JSON이 잘못된 이유를 알고 싶다면 예외에서 캐치 블록 내부를 조사할 수 있습니다.단, 고객님의 문제라 하더라도 인터넷에서 수신한 JSON을 수정하는 것은 클라이언트의 책임이 아닙니다.
어느 쪽이든 JSON이 불량해졌을 때 어떻게 할지 결정하는 것은 클라이언트의 책임입니다.두 가지 가능성은 JSON을 거부하고 아무것도 하지 않고 다시 시도하는 것입니다.
다시 시도하려면 try/catch block 안에 플래그를 설정하고 try/catch block 밖에서 플래그를 응답하는 것을 강력히 권장합니다.중첩된 시도/캐치는 스택 추적과 예외가 일치하지 않는 상태에서 Gson이 우리를 이 혼란에 빠뜨린 원인일 수 있습니다.
즉, 외모가 우아해 보이지는 않지만, 추천하고 싶은 것은
boolean failed = false;
try
{
gson.fromJSON(ad, Ad.class);
//...
}
catch (IllegalStateException | JsonSyntaxException exception)
{
failed = true;
//...
}
if (failed)
{
//...
Retrofit2에서 모수를 원시 상태로 보내려면 스칼라를 사용해야 합니다.
먼저 그래들 안에 다음 내용을 추가합니다.
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);
}
my sample Activity :
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) {
}
}
참고 자료: [Retrofit 요청 본문에 전체 JSON을 POST하는 방법]
이치노 후 했습니다. Notbook입니다. 가능한 해결책입니다.clean preject
.
나도 최근에 비슷한 문제를 겪었는데 흥미로운 해결책을 찾았어.기본적으로 다음 네스트된 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\"}}}"
결국 regex를 사용하여 JSON의 시작과 끝부분에서 열린 따옴표를 삭제하고 apache.comms unescapeJava() 메서드를 사용하여 이스케이프를 해제했습니다.기본적으로 부정 JSON을 다음 방법으로 전달하여 깨끗한 JSON을 되찾았습니다.
private String removeQuotesAndUnescape(String uncleanJson) {
String noQuotes = uncleanJson.replaceAll("^\"|\"$", "");
return StringEscapeUtils.unescapeJava(noQuotes);
}
Google GSON을 사용하여 자신의 오브젝트로 해석합니다.
MyObject myObject = new.Gson().fromJson(this.removeQuotesAndUnescape(uncleanJson));
아마도 당신의JSON Object
맞지만, 당신이 받은 답변은 당신의 유효한 데이터가 아닙니다. 접속 WiFi
한 대답을 수 < html>.....< /html>
그그GSON
해석할 수 없습니다.
때 '어느 정도'를 할 수도 있어요.try..catch..
이 이상한 반응으로 충돌을 피할 수 있습니다.
DATE/DATETIME 등의 DESERIALIZED 객체가 있는지 확인합니다.JSON을 역직렬화하지 않고 직접 송신하는 경우 이 문제가 발생할 수 있습니다.
상황에는 몇 String이 1개의 파라미터는 배열입니다.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의 .Adapter
BaseModel
Json 오브젝트되어 String
★★★★★★★★★★★★★★★★★」byte[]
이데올로기 때문에, ★★★★★★★★★★★★★.Gson
상황이 별로 마음에 들지 않아요
는 결국 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.Adapter
byte[]
is is is is is로 됩니다.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[]
class에서 class)로 합니다.Adapter
JSONObject / 로 j j j j j j j j로 j j j j j j j j j j j j 。
마세요jsonObject.toString
JSON 오브젝트 위에 있습니다.
제 경우 JSON 오브젝트를 다음과 같이 반환하고 있습니다.
{"data":","message":"출석이 성공적으로 저장되었습니다.!!" "status" "success"}
다음과 같이 변경하여 해결합니다.
{"data":{},"message":"출석이 성공적으로 저장되었습니다.!!" "status" "success"}
여기서 데이터는 하위 Json Object이며 ""이(가) 아닌 {}부터 시작해야 합니다.
json 형식과 변수가 정상이면 데이터베이스 쿼리를 체크합니다.데이터가 올바르게 db에 저장되어 있어도 실제 문제는 거기에 있을 수 있습니다.쿼리를 다시 확인하고 다시 시도하십시오.도움이 되었으면 좋겠다
먼저 Gson()을 사용하여 객체를 Json으로 변환하는 것을 잊지 마십시오.
val fromUserJson = Gson().toJson(notificationRequest.fromUser)
그러면 이 멋진 라이브러리를 사용하여 쉽게 오브젝트로 되돌릴 수 있습니다.
val fromUser = Gson().fromJson(fromUserJson, User::class.java)
손으로 쓴 json 파일을 읽은 적이 있어요.Json은 완벽해.그러나 이 오류가 발생했습니다.java 객체에서 json 파일로 쓰고 그 json 파일에서 읽습니다.모든 게 괜찮아손으로 쓴 json과 java 오브젝트의 차이를 알 수 없었습니다.비교 이상으로 시험해 본 결과 차이가 없습니다.두 개의 파일 사이즈가 조금씩 다르다는 것을 알게 되어 winHex 툴을 사용하여 여분의 것을 검출했습니다.그래서 제 상황에 맞는 해결책은 좋은 json 파일을 복사해서 거기에 콘텐츠를 붙여넣고 사용하는 것입니다.
제 경우 커스텀http-client가 gzip 인코딩을 지원하지 않았습니다."Accept-Encoding: gzip" 헤더를 전송 중이었기 때문에 응답이 gzip 문자열로 반환되어 복호화할 수 없었습니다.
해결책은 그 헤더를 보내지 않는 것이었습니다.
Android의 Retrofit을 사용하여 POST 요청을 하고 있었습니다.
당면한 과제:
Android Studio logcat에서 발생한 오류:
java.displaces를 클릭합니다.InlawalStateException:BEGIN_OBJECT가 필요한데 2행 1패스 $에 STRING이었습니다.
[하지만 VOLY 라이브러리에서는 잘 작동]
검색했을 때...[분명히 json은 오브젝트를 기대하고 있지만...]
그러나 간단한 문자열 [print_r("don't loses hope")]또는 [Noting]를 반환하도록 서비스를 변경했을 때
Postman에서는 정상적으로 인쇄되고 있었지만, Android studio logcat에서는 여전히 SAME ERROR였습니다.
java.displaces를 클릭합니다.InlawalStateException:BEGIN_OBJECT가 필요한데 2행 1패스 $에 STRING이었습니다.
]
잠깐만요, 간단한 메시지를 보내거나 답장을 보내지 않고 있는데 스튜디오에서 계속...BEGIN_OBJECT가 필요한데 STRING..." SOMTHING IS WRIGHT
4일째:나는 마침내 "Q"를 보기 위해 멈췄다.UICK SOLUTIONS" 및 스택 오버플로우 관련 질문과 기사를 주의 깊게 읽어보십시오.
입수 내용:
서버(에코 메시지)에서 가져온 데이터 중 Andorid studios logcat에 표시되지 않은 데이터가 모두 표시되므로 문제를 찾을 수 있습니다.
제가 발견한 것은 @Body like-로 데이터를 전송하고 있었다는 것입니다.
@Headers("Content-Type: application/json")
@POST("CreateNewPost")
Call<Resp> createNewPost(@Body ParaModel paraModel);
그러나 서버에 도달한 파라미터는 없습니다.모든 것이 null입니다[Logging interceptor를 사용하여 찾았습니다]
그리고 단순히 "Retrofit을 사용하여 POST 요청을 만드는 방법"이라는 기사를 검색했습니다.
해결책:
여기서부터 방법을 다음과 같이 변경했습니다.
@POST("CreateNewPost")
@FormUrlEncoded
Call<Resp> createNewPost(
@Field("user_id") Integer user_id,
@Field("user_name") String user_name,
@Field("description") String description,
@Field("tags") String tags);
모든 게 괜찮았어요
결론:
Retrofit이 왜 이 오류를 발생시켰는지 이해할 수 없습니다.
java.displaces를 클릭합니다.InlawalStateException:BEGIN_OBJECT가 필요한데 2행 1패스 $에 STRING이었습니다.
전혀 말이 안 돼요
따라서 항상 상세하게 디버깅한 후 누출되는 부분을 찾아 수정하십시오.
This error solved for by replacing .toString method to .string on the response
toString => string (add in try{...code..}catche(IOException e))
below code is working for me
try {
MainModelResponse model;
Gson gson = new GsonBuilder().create();
if (response.code() == ConstantValues.SUCCESS_OK) {
model = gson.fromJson(response.body().string(), MainModelResponse.class);
} else {
model = gson.fromJson(response.errorBody().string(), MainModelResponse.class);
}
moduleData.postValue(model);
}catch (IllegalStateException | JsonSyntaxException | IOException exception){
exception.printStackTrace();
}
}
{} 로 시작하는 문자열과 끝나는 문자열을 사용합니다.
예를 들어
final String jsStr = "{\"metric\":\"opentsdb_metric\",\"tags\":{\"testtag\":\"sunbotest\"},\"aggregateTags\":[],\"dps\":{\"1483399261\":18}}";
DataPoint dataPoint = new Gson().fromJson(jsStr, DataPoint.class);
난 이거면 돼
내 경우 Json Validator가 유효한 응답을 주는데도 개체는 모두 정상이었지만 나는 이렇게 인터페이스를 사용하고 있었다.
@POST(NetworkConstants.REGISTER_USER)
Call<UserResponse> registerUser(
@Query("name") String name,
@Query("email") String email,
@Query("password") String password,
@Query("created_date") Long creationDate
);
그 후 코드를 로 변경했습니다.
@FormUrlEncoded
@POST(NetworkConstants.REGISTER_USER)
Call<UserResponse> registerUser(
@Field("name") String name,
@Field("email") String email,
@Field("password") String password,
@Field("created_date") Long creationDate
);
그리고 모든 것이 해결되었다.
코드와 관련이 없는 문제
다른 프로젝트에서 일부 파일을 복사한 후 이 문제가 발생했습니다.
스택에서 Gson 라이브러리를 가리킵니다.
Android studio 4.2.1에서는 파일을 사용해도 이 문제가 해결되지 않습니다.-> 무효화 후 재시작합니다.
그리고.
첫 번째 빌드에서 재시작 후 동일한 오류가 발생했지만 두 번째 빌드에서는 이 문제가 해결되었습니다.
왜 이런 일이 일어났는지 모르겠다
나는 오래된 버전의 리트로핏 도서관을 사용하고 있었다.그래서 제가 해야 할 일은 코드를 업그레이드한 후 이 코드부터com.squareup.retrofit2:retrofit:2.9.0
:
@POST(AppConstants.UPLOAD_TRANSACTION_DETAIL)
fun postPremiumAppTransactionDetail(
@Query("name") planName:String,
@Query("amount") amount:String,
@Query("user_id") userId: String,
@Query("sub_id") planId: String,
@Query("folder") description:String,
@Query("payment_type") paymentType:String):
Call<TransactionResponseModel>
이를 위해:
@FormUrlEncoded
@POST(AppConstants.UPLOAD_TRANSACTION_DETAIL)
fun postPremiumAppTransactionDetail(
@Field("name") planName:String,
@Field("amount") amount:String,
@Field("user_id") userId: String,
@Field("sub_id") planId: String,
@Field("folder") description:String,
@Field("payment_type") paymentType:String):
Call<TransactionResponseModel>
언급URL : https://stackoverflow.com/questions/28418662/expected-begin-object-but-was-string-at-line-1-column-1
'programing' 카테고리의 다른 글
Vuex 및 웹소켓 (0) | 2022.08.09 |
---|---|
자바 메모리 풀은 어떻게 분할됩니까? (0) | 2022.08.09 |
기존 웹 페이지 내에서 npm 없이 구성 요소 사용 (0) | 2022.08.09 |
argc가 넘칠 수 있나요? (0) | 2022.08.09 |
Vue-router를 사용한 Firebase 인증 확인 (0) | 2022.08.09 |