어제 났던 에러
com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 8 path $
해결방법을 서칭하는 중이다
MalformedJsonException 에러는
Restful api를 지원하는 서버와 통신하기 위해 gson을 사용하는 경우에 발생 할 수있고
발생한 이유는 gson에서 json을 처리할 때 json 형식의 RFC 4627을 엄격하게 지키지 않아서라는데 (json data에 불필요한 값이나 띄어쓰기가 있는 경우 등등)
해결방법은
다른 사람들이 규격을 어긴 예시를 보면 끝에 ,를 붙였다든지 하는 것들이었는데, 나는 꼼꼼히 찾아봐도 보이지 않아서 setLenient()를 사용해보려고 한다
또 다른 곳에서 본 에러의 이유!
외부 API에서 받은 JSON 데이터가 올바른 형식이 아니거나 손상되었을 때,
일반적으로 Gson은 엄격한 JSON 파싱을 수행하는데
이때 JSON 데이터가 완벽하게 형식에 맞지 않으면 Gson이 파싱을 거부하고 'MalformedJsonException'과 같은 예외를 던질 수 있다
그러나 실제 상황에서는 외부 API에서 받은 JSON 데이터가 항상 완벽하게 형식에 맞지 않을 수 있는일(API 응답이 부분적으로 손상되었거나, 예상하지 못한 문자열이 포함)이 많은데,
이런 경우, 'JsonReader.setLenient(true)'를 호출하여 JsonReader 객체를 설정하면 Gson은 보다 관대하게 JSON 데이터를 파싱하고, 형식에 맞지 않는 부분을 무시하고 파싱을 진행한다
ApiParseContoller의 윗 부분은 생략하고, json 파싱 부분만 보자면
// jsonParser를 사용해서 string 값을 json객체로 만들어준다
JsonParser parser = new JsonParser();
JsonReader reader = new JsonReader(new StringReader(sb.toString()));
reader.setLenient(true);
// 만들어진 json객체는 jsonObject클래스를 사용해서 저장된다
JsonObject obj = parser.parse(reader).getAsJsonObject();
JsonObject responseBody = obj.getAsJsonObject("response").getAsJsonObject("body");
if (responseBody != null) {
JsonArray items = responseBody.getAsJsonObject("items").getAsJsonArray("item");
for (JsonElement jsonElement : items) {
JsonObject temp = jsonElement.getAsJsonObject();
String mtName = temp.has("frtrlNm") ? temp.get("frtrlNm").getAsString() : "";
String mtLocation = temp.has("addrNm") ? temp.get("addrNm").getAsString() : "";
int mtHeight = temp.has("aslAltide") ? temp.get("aslAltide").getAsInt() : 0;
Mountain mountain = Mountain.builder()
.mtName(mtName)
.mtLocation(mtLocation)
.mtHeight(mtHeight)
.build();
}
}
JsonParser parser = new JsonParser();
JsonReader reader = new JsonReader(new StringReader(sb.toString()));
reader.setLenient(true);
JsonObject obj = parser.parse(reader).getAsJsonObject();
이 코드들을 실행시키면 또 다른 500에러가 난다
