반응형

https://curlconverter.com/

Python 뿐만 아니라 Java 등 다른 여러 개발 언어들로도 curl을 코드로 변환하는 것이 가능하다. 최고다... 👍

 

 

 

반응형
반응형

발생 오류와 코드 그리고 발생했던 이유 : 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());

 

반응형
반응형

Python HTTP cURL reponse body 가져오는 법

r = requests.get("http://www.google.com")
print(r.content)
반응형
반응형
Traceback (most recent call last):
  File "/file.py", line 29, in <module>
    lines = f.readline()
io.UnsupportedOperation: not readable

읽고 쓰기 옵션을 'w' -> 'r' 로 수정하면 io.UnsupportedOperation: not readable 오류 해결 가능.

f = open(work_path + "/file.data", 'w')

↓

f = open(work_path + "/file.data", 'r')

 

 

 

반응형
반응형

※ 구글링해도 못 찾아서 내가 땅 한번 파보고 쓰는 블로그 ※

 

 전제 1 

나는 여행 계획을 짜려고 한다. 르뱅쿠키도 먹고 싶고 미스사이공 뮤지컬도 보고 싶은데, 어디 좋은 곳 없을까?

그래서 난 MongoDB 데이터베이스에서

  1. 자유여행 이면서
  2. 르뱅베이커리쿠키를 먹고
  3. 미스사이공 뮤지컬도 볼 수 있는

도시가 포함된 여행 계획들을 검색하고자 한다.

 

 MongoDB 도큐먼트 구조 

// doc 1
{
   "tripId": "AABB123",
   "tripLoc": "Domestic",
   "tripType": "free",
   "cities": [
      {
         "cityName": "Seoul",
         "todo": [
            {
               "category": "eat",
               "name": "levainbakery"
            },
            {
               "category": "musical",
               "name": "Miss Saigon"
            }
         ]
      },
      {
         "cityName": "Daejeon",
         "todo": [
            {
               "category": "eat",
               "name": "sunsimdang"
            }
         ]
      }
   ]
}

// doc 2
{
   "tripId": "CCDD456",
   "tripLoc": "Overseas",
   "tripType": "free",
   "cities": [
      {
         "cityName": "NY",
         "todo": [
            {
               "category": "eat",
               "name": "levainbakery"
            },
               {
               "category": "eat",
               "name": "Red Poke"
            }
         ]
      }
   ]
}

 MongoDB 검색 쿼리 

db.test.find(
{ "tripType" : "free",
  "cities" : { "$elemMatch" : { "$and" : [
    { "todo" : { "$elemMatch" : { "category" : "eat", "$and" : [{ "name" : "levainbakery"}]}}},
       { "todo" : { "$elemMatch" : { "category" : "musical", "$and" : [{ "name" : "Miss Saigon"}]}}}]}}}
).pretty()
// 검색 결과
{
        "_id" : ObjectId("60f90701ef19bebb6341907e"),
        "tripId" : "AABB123",
        "tripLoc" : "Domestic",
        "tripType" : "free",
        "cities" : [
                {
                        "cityName" : "Seoul",
                        "todo" : [
                                {
                                        "category" : "eat",
                                        "name" : "levainbakery"
                                },
                                {
                                        "category" : "musical",
                                        "name" : "Miss Saigon"
                                }
                        ]
                },
                {
                        "cityName" : "Daejeon",
                        "todo" : [
                                {
                                        "category" : "eat",
                                        "name" : "sunsimdang"
                                }
                        ]
                }
        ]
}

// 검색 결과에서 난 tripId만 보고 싶다. default로 보여지는 _id도 안 보고싶다. 
db.test.find(
{ "tripType" : "free",
  "cities" : { "$elemMatch" : { "$and" : [
    { "todo" : { "$elemMatch" : { "category" : "eat", "$and" : [{ "name" : "levainbakery"}]}}},
       { "todo" : { "$elemMatch" : { "category" : "musical", "$and" : [{ "name" : "Miss Saigon"}]}}}]}}}
, {tripId : 1, _id : 0}).pretty() 
 // 검색 결과
 { "tripId" : "AABB123" }

 JAVA 코드 

@Override
public Schedule getTourSchedule() {
    Query query = new Query();
    query.addCriteria(Criteria.where("tripType").is("free"));

    List<Criteria> todoCriteria = new ArrayList<>();
    todoCriteria.add(Criteria.where("todo").elemMatch(
            Criteria.where("category").is("eat").andOperator(Criteria.where("name").is("levainbakery"))));
    todoCriteria.add(Criteria.where("todo").elemMatch(
            Criteria.where("category").is("musical").andOperator(Criteria.where("name").is("Miss Saigon"))));
    query.addCriteria(Criteria.where("cities").elemMatch(new Criteria().andOperator(todoCriteria.toArray(new Criteria[todoCriteria.size()]))));

    return mongoTemplate.find(query, Schedule.class);
}

 전제 2 

르뱅 베이커리레드포케를 먹을 수 있는 여행 계획을 짜고 싶다.

 MongoDB 검색 쿼리 

db.test.find(
{ "tripType" : "free",
  "cities" : { "$elemMatch" : { "$and" : [
  { "todo" : { "$elemMatch" : { "category" : "eat", "$and" : [{ "name" : "levainbakery"}]}}},
  { "todo" : { "$elemMatch" : { "category" : "eat", "$and" : [{ "name" : "Red Poke"}]}}}]}}}
, {tripId : 1, _id : 0}).pretty()
// 검색 결과
{ "tripId" : "CCDD456" }

JAVA 코드 : For문을 이용하여 이중 배열 찾는 쿼리 예제 

@Override
public Schedule getTourSchedule() {

    Query query = new Query();
    query.addCriteria(Criteria.where("tripType").is("free"));

    List<String> goList = new ArrayList<>(); // 가고 싶은 음식점 리스트
    goList.add("levainbakery");
    goList.add("Red Poke");

    List<Criteria> todoCriteria = new ArrayList<>();
    for (String storeName : goList) { // For문을 활용하여 가고 싶은 음식점 리스트를 기반으로 쿼리 생성
        todoCriteria.add(Criteria.where("todo").elemMatch(
                Criteria.where("category").is("eat").andOperator(Criteria.where("name").is(storeName))));
    }
    query.addCriteria(Criteria.where("cities").elemMatch(new Criteria().andOperator(todoCriteria.toArray(new Criteria[todoCriteria.size()]))));

   return mongoTemplate.find(query, Schedule.class);
}

 

끄읕ⓙ

반응형

+ Recent posts