2016-06-06 4 views
0

나는 가독성을 위해 디코딩 한 다음과 같은 webhook POST의 수신자입니다. 스프링 MVC를 사용Jackson과 함께 JSON에 대한 연관 배열 요청 매개 변수 변환

id=12345&event=this_event&payload[customer][name]=ABC Company&payload[customer][city]=New York&payload[service][name]=New Customer&payload[service][action]=New 

, 내가 쉽게 JSON에 "페이로드"로 시작 나는 모든 매개 변수를 구문 분석 (또는 키지도)하기 위해 필요한이

{id=97659204, event=test, payload[customer][name]=ABC Company, payload[customer][city]=New York, payload[service][name]=New Customer, payload[service][action]=New} 

처럼 보이는 Map<String, Sting>에이를 얻을 수 있습니다 목적.

"페이로드"로 시작하는 요청 매개 변수를 구문 분석에서 내 원하는 출력은 최종 상태는 POJO로 JSON 것을 설정하는 잭슨의 ObjectMapper를 호출되고이

{ 
    customer : { 
     name : "ABC Company", 
     city : "New York" 
    }, 
    service : { 
     name : "New Customer", 
     action : "New" 
    } 
} 

처럼 보일 것입니다.

나에게 보낸 데이터 형식을 제어 할 권한이 없으므로 이러한 요청 매개 변수를 JSON 개체로 구문 분석하기위한 최상의/올바른 옵션은 무엇입니까?

감사합니다.

답변

0

페이로드 [] [] [] 매개 변수가 전달되는 사용자 지정 파서가 작성되었습니다. 정규식 정규 표현식을 사용한 다음 각 매개 변수를 분석하고 재귀를 사용하여 1 ... n 맵의 맵을 탐색 한 다음 결과적으로 Map은 완벽한 JSON을 만듭니다.

@RequestMapping(value = "/receiver", method = RequestMethod.POST) 
@ResponseBody 
public void receiver(@RequestParam Map<String, Object> requestBody) throws IOException { 

    Pattern pattern = Pattern.compile("\\[([^\\]]+)]"); 

    Map<String, Object> payloadMap = new HashMap<>(); 
    Matcher matcher = null; 
    List<String> levels = null; 

    for (String key : requestBody.keySet()) { 

     if (key.startsWith("payload")) { 

      matcher = pattern.matcher(key); 
      levels = new ArrayList<>(); 
      while (matcher.find()) { 
       levels.add(matcher.group(1)); 
      } 

      payloadMap = nestMap(payloadMap, levels.iterator(), (String) requestBody.get(key)); 

     } 
    } 

    LOG.debug(mapper.writeValueAsString(payloadMap)); 

} 

@SuppressWarnings("unchecked") 
private Map<String, Object> nestMap(Map<String, Object> baseMap, Iterator<String> levels, String value) { 

    String key = levels.next(); 

    if (!levels.hasNext()) { 
     baseMap.put(key, value); 
    } else { 
     if (!baseMap.containsKey(key)) { 
      baseMap.put(key, nestMap(new HashMap<String, Object>(), levels, value)); 
     } else { 
      baseMap.put(key, nestMap((Map<String, Object>) baseMap.get(key), levels, value)); 
     } 
    } 

    return baseMap; 

}