programing

"BEGIN_OBJECT가 필요하지만 1행 1열에 STRING이었습니다."

projobs 2022. 8. 9. 22:47
반응형

"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의 .AdapterBaseModelJson 오브젝트되어 String ★★★★★★★★★★★★★★★★★」byte[]이데올로기 때문에, ★★★★★★★★★★★★★.Gson상황이 별로 마음에 들지 않아요

는 결국 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.Adapterbyte[] 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)로 합니다.AdapterJSONObject / 로 j j j j j j j j로 j j j j j j j j j j j j 。

마세요jsonObject.toStringJSON 오브젝트 위에 있습니다.

제 경우 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

반응형