티스토리 뷰
[JAVA] com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON 오류 해결하기
뜌듑 2021. 12. 3. 23:59발생 오류와 코드 그리고 발생했던 이유 : com.google.gson.stream.MalformedJsonException
com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 7 path $
// 오류 발생 코드
httpMessage.setPayload(gson.fromJson(jsonString, JsonElement.class).getAsJsonObject());
API request, response를 로깅을 하는 과정에서 오류 발생하였는데,
String jsonString에 들어있던 스트링의 내용이 Json 포맷이 아닌데 getAsJsonObject()을 하려 했기 때문이다.
안 좋은 JsonString 예 )
String jsonString = "http://zi-c.tistory.com/asbcdfdasf?%Fsfsdf%sdfafsfsdk"
↑ 이런 식으로 스트링 형식에 특수 문자도 들어있었다.
좋은 JsonString 예 )
String jsonString = "{ \"name\" : \"뜝\"}"
↑ 이런 식으로 JsonObject가 스트링화 된 형태였어야 jsonElement로 변환 후 getAsJsonObject해도 정상적으로 Object화 됨.
해결법 : TRY - CATCH를 활용하자!
항상 비-Json 형식의 스트링이 들어올 수 밖에 없는 상황이였으므로,
JsonElement의 parseReader 함수를 사용하여 MalformedJsonException을 발생할 때를 예외 처리를 해주었다.
parseReader 함수는 MalformedJsonException이 발생하면 JsonSyntaxException을 throw 해주기 때문에 Try-Catch를 활용하여 예외처리를 할 수 있었다.
해결 코드
JsonParser에서 JsonSyntaxException이 발생한 경우, String을 json-포맷화 하여 다시 설정해주고 다시 동일한 코드를 실행시켜주었다.
import com.google.gson.JsonParser;
try {
httpMessage.setPayload(JsonParser.parseString(jsonString).getAsJsonObject());
} catch (JsonSyntaxException e) {
jsonString = "{ \"log\" : \"" + jsonString + "\"}";
httpMessage.setPayload(JsonParser.parseString(jsonString).getAsJsonObject());
}
* 이 코드를 사용하는 함수 단에서 IOException을 throw 하고 있었기 때문에 catch (MalformedJsonException e) 로는 예외 처리가 불가능 하였다. 다행히 JsonParser를 활용하여 해결하였다.
package com.google.gson;
public static JsonElement parseReader(Reader reader) throws JsonIOException, JsonSyntaxException {
try {
JsonReader jsonReader = new JsonReader(reader);
JsonElement element = parseReader(jsonReader);
if (!element.isJsonNull() && jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonSyntaxException("Did not consume the entire document.");
} else {
return element;
}
} catch (MalformedJsonException var3) {
throw new JsonSyntaxException(var3);
} catch (IOException var4) {
throw new JsonIOException(var4);
} catch (NumberFormatException var5) {
throw new JsonSyntaxException(var5);
}
}
내가 해본 시도들
시도 1 : setLenient(true) 하라길래 해봄... 안됨
결과 : 새로운 Exception 발생 - com.google.gson.JsonPrimitive cannot be cast to com.google.gson.JsonObject
JsonReader reader = new JsonReader(new StringReader(jsonString));
reader.setLenient(true);
httpMessage.setPayload(gson.fromJson(reader, JsonElement.class));
시도 2 : getAsJsonObject 안 하게 바로 JsonObject.class로 받아봄... 안됨
결과 : 새로운 Exception 발생 - Expected a com.google.gson.JsonObject but was com.google.gson.JsonPrimitive
httpMessage.setPayload(gson.fromJson(jsonString, JsonObject.class));
시도 3 : 구글링 해서 코드를 바꿔봄... 안됨
결과 : 새로운 Exception 발생 - com.google.gson.JsonSyntaxException: Expected a com.google.gson.JsonObject but was com.google.gson.JsonPrimitive
JsonReader reader = new JsonReader(new StringReader(jsonString));
reader.setLenient(true);
httpMessage.setPayload(gson.fromJson(reader, JsonObject.class));
시도 4 : 안됨
string 이라 primitive type에서 분류될 것이라 생각하였는데, else로 타고 들어가지더라.
JsonElement jsonElement = gson.fromJson(jsonString, JsonElement.class);
if (jsonElement.isJsonPrimitive()) {
JsonObject jsonObject = new JsonObject();
jsonObject.add("logContent", jsonElement);
httpMessage.setPayload(jsonObject);
}
else
httpMessage.setPayload(jsonElement.getAsJsonObject());
'괴발개발' 카테고리의 다른 글
[우분투] /usr/bin/python3: No module named pip 해결하기 (0) | 2021.12.10 |
---|---|
curl Python/Java requests 코드로 변환하기 👍 (0) | 2021.12.04 |
Python HTTP cURL response body 가져오기 (0) | 2021.11.10 |
Python io.UnsupportedOperation: not readable 오류 해결하기 (0) | 2021.11.10 |
[JAVA] 몽고디비 이중 배열 검색하기 (MongoDB Nested Array Search) (0) | 2021.07.22 |