Jackson ObjectMapper 로 가져온 JSON MAP으로 꺼내기

사내 시스템에서 외부 API를 JSON으로 받아오는 부분이 있는데

이 받아온 JSON을 Jackson으로 변환한 후 Map형식으로 변환한 데이터를

화면 프레임워크에 IO로 전달하는 방식으로 구현되어 있었다.

그런데 화면 프레임워크 IO에서 계층 JSON을 변환 지원을 못한다고 한다.

특정 업무에서 계층형 JSON을 전달받는 API가 있는데

계층 안에 들어가있는 값을 화면에서 써야 되서

Jackson에서 JSON 변환한 Map 객체에서

계층으로 들어가 있는 Map 객체를 꺼내고 다시 가공해서 화면으로 보내도록 개발했다.

 

public class ResponseClass {
    private String id;
    private Object result;
    private Object detail;
    
    pubic void setId(String id) {
        this.id= id;
    }

    public String getId() {
        return id;
    }

    pubic void setResult(Object result) {
        this.result = result;
    }

    public Object getResult() {
        return result;
    }

    pubic void setDetail(Object detail) {
        this.detail= detail;
    }

    public Object getDetail() {
        return detail;
    }

우선 위와 같이 응답받은 JSON을 변환할 setter/getter class를 만든다.

 

// 응답받은 JSON
String sJson = "{\"id\":\"aa\", \"result\": {\"code\": \"00\", \"detail\":{\"val\":\"hi~\"}}}";

// readValue로 데이터 클래스에 꺼내오기
ResponseClass oConts = new ObjectMapper().readValue(sJson , ResponseClass);

// MAP으로 변환 된 계층 JSON값 가져오기
Object oDetail = ((Map<String,Object)) oConts.getResult()).get("detail");

// detail 객체 셋팅
oConts.setDetail(oDetail);

JSON 안에 계층으로 들어가있는 JSON은 Map으로 변환되고

그 안에 있는 JSON도 Map으로 변환되는 구조이다.

(Jackson을 처음 수정해봐서 Map으로 변환되는걸 몰라서 삽질 한참 했음ㅠㅠ)

그런데 프레임워크에서 단일 map만 io로 지원을 해줘서

각각 꺼내서 화면으로 넘겨줘야 했다.

그래서 result Map에서 detail 맵을 꺼내서 셋팅 해주었다 !!

프레임워크에서 CLOB 조회를 지원하지 않는다..

사내시스템에서 에디터 기능이 포함된 게시판 화면을 추가하는 요구사항이 들어왔다.

현 사내시스템은 게시판 기능 없이 업무 처리 위주로 구성되어 있어서

처음으로 에디터(HTML) 기능이 포함된 게시판이 생기는 것이다 !

에디터로 글을 작성하면 태그 때문에 데이터가 길어져서

VARCHAR2 최대 크기인 4000bytes로는 턱없이 부족해서 협의 후 CLOB 를 사용하기로 했다.

그런데 ?

Oracle DB에서는 CLOB 컬럼을 지원 했지만

프레임워크에서 CLOB 데이터값을 지원하지 않아 IO에 담지 못하는 상황이 발생했다.

문의해보니 VARCHAR2 타입으로 변환헤서 화면단으로 넘기라고 답변 받았다.

그래서 CLOB 데이터를 VARCHAR2 4000bytes 이하 크기로 나눠서

여러 행으로 조회하고, 화면에서는 조회된 데이터를 붙여서 보여주는 방법으로 해결했다.

 

오라클 계층형 구조 CONNECT BY

오라클 계층형 구조 CONNECT BY 를 이용하여

CLOB 긴 데이터를 나눠서 여러행으로 조회할 수 있다.

* 주요 문법

- Connect By : 트리 형태의 구조로 질의를 수행하는 것

- Start with : 시작조건 (최상위 값이 시작하는 곳)

- Connect by prior : 조인조건

추가 예시는 아래 링크 참고 !

https://blog.naver.com/kbeeysk/221710976391

 

쿼리

SELECT  TB.P_KEY
       ,TB.TITLE
       ,TB.CONTENTS
FROM 
(

SELECT A.P_KEY
      ,A.TITLE
      ,DBMS_LOB.SUBSTR(TB.CONTENTS,1000,(LEVEL-1)*1000+1) CONTENTS    
FROM BOARD_TABLE A
WHERE A.P_KEY = #P_KEY#
) TB
START WITH TB.P_KEY = #P_KEY#
CONNECT BY LEVEL <= CEIL(LENGTH(TB.CONTENTS/1000)

조회 테이블을 한번 감싸줘야 데이터가 안꼬여서 감싸줬고

START WITH를 꼭 해줘야 해당 게시글 데이터만 딱 나오니 꼭 해줘야 한다.

(안해주면 꼬일 수 있음..)

레벨은 4000bytes로 했다가 혹시나 초과될 것을 대비해서 안정적으로 1000bytes로 나눠주었다.

이렇게 여러행으로 조회 해 온 후 화면에서 붙여서 보여주니 잘 조회됐다 ~!

ORACLE CLOB 컬럼인데 4000Byte 이상 INSERT 시 오류가 발생 했다..

CLOB 컬럼에 4000byte 이상 값을 INSERT / UPDATE 할 경우

ORA-01461: LONG 값은 LONG 열에만 입력할 수 있습니다 오라클 에러가 발생했다

4000bytes 이상 데이터를 저장하기 위해 VARCHAR2안쓰고

CLOB를 사용했는데 에러가 발생했다 :( ...

 

원인은 오라클 String타입 함수

INSERT INTO TABLE_NAME
(
COLUMN_MN
)
VALUES
(
NVL (#COLUMN_NAME#, ' ')
)

오류 원인은 INSERT 쿼리에서 VALUES값 셋팅 시

NVL을 사용함으로 인해서 String 타입으로 자동 변환되서

4000bytes 이상 값이 들어왔을 때 에러가 발생한 것이다.

 

오라클 함수를 안쓰니까 해결!

INSERT INTO TABLE_NAME
(
COLUMN_MN
)
VALUES
(
#COLUMN_NAME#
)

NVL 빼버리고 바로 값 셋팅하니 정상 동작 됐다 -!

 

+ Recent posts