ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • thymeleaf inline javascript 사용하기 & jackson json 으로 변환하기
    Back-end 2015. 4. 25. 19:46
    728x90
    웹 개발시 html 템플릿 엔진으로 thymeleaf 를 사용할때 인라인 자바 스크립트라는 기능에 대해서 소개하고 현재 버전이 가지고 있는 문제점을 해결할 수 있는 방법을 전달한다.

    인라인 자바스크립트(inline javascript) 사용

    <script th:inline="javascript" type="text/javascript">
        //서버에서 view 로 넘긴값을 html의  javascript에 json 형태로 넘김.
        var domain = /*[[${domain}]]*/
    </script>

    위와 같은 형태로 사용한다. 

    여기서 인라인이라는 의미는 서버에서 뷰생성을 위한 데이터를 웹브라우저로 그대로 넘긴다는 의미로 볼 수 있다. 이렇게 넘기는 객체를 json으로 변환해서 변수에 할당하면 javascript 라이브러리에서 바로 사용할 수 있다.
    이런 기능이 없다면 최초의 데이터는 서버스크립트로 처리하고 자바스크립트에서 데이터를 읽어오기 위해서는 ajax로 별도의 서버요청을 통해서 데이터를 읽어와야 한다.




    json 포맷 이슈
    인라인 자바스크립트를 사용하다 발견한 문제점이 있다. Enum 타입의 자바 객체를 json으로 변환되는 포맷이 기존 자바쪽에서 사용하던 라이브러리(jackson json)와 달랐다.


    Enum 타입 변환 결과 차이 비교
    java Enum 객체
    public enum UseStatus {
        enable, disable
    }


    thymeleaf에서 변환
    {
        "useStatus" : {
            "$type": "UseStatus",
            "$name": "enable"
        }
    }


    jackson json에서 변환
    {
        "useStatus" : "enable"
    }

    이렇게 차이가나니 ajax로 전달받은 데이터와 인라인으로 전달받은 json이 서로 포맷이 달라서 처리에 애로 사항이 발생했다.
    또한 jackson json에서 Annotation을 이용해서 json변환 포맷을 조절할 수 있는데 이런 기능들을 사용할 수 없게 된다.

    인라인 자바스크립트 json 변환을 할때 사용자가 지정한 외부 라이브러리를 통해서 변환 할 수 있도록 해줘야 하는데 현재까지 인런 기능은 구현되지 않고 있다. 2015년 중에 thymeleaf 3 버전이 나온다고 하는데 그때 이기능이 포함되어 있을 예정이라고 한다. thymeleaf3 버전이 나오지 않은 현재 시점에 jackson json등 외부 라이러리를 사용하려면 thymeleaf에서 json 변환하는 부분을 재정의 해서 처리하는 방법을 사용해야 한다.

    해결법
    thymeleaf에세 인라인 자바스크립트 json 변환을 실행하는 객체는 org.thymeleaf.standard.inliner.StandardJavaScriptTextInliner 클래스이다. 이 클래스를 개발진행중인 프로젝트에서 같은 패키지에 같은 클래스명으로 재정의를 한다면 JVM에서는 이렇게 재정의한 클래스를 먼저 찾게 된다. 아래는 jackson json라이브러리로 재정의한 코드 샘플이다.

    package org.thymeleaf.standard.inliner;

    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;

    public class StandardJavaScriptTextInliner extends AbstractStandardScriptingTextInliner {
         
         public static final StandardJavaScriptTextInliner INSTANCE = new StandardJavaScriptTextInliner();
         
         ObjectMapper objectMapper = new ObjectMapper();
         
         private StandardJavaScriptTextInliner() {
              super();
         }

         @Override
         protected String formatEvaluationResult(Object result) {
              try {
                   return objectMapper.writeValueAsString(result);
              } catch (JsonProcessingException e) {
                   e.printStackTrace();
              }
              
              return "json 변환 에러!!";
         }

    }





    참고할 페이지




Designed by Tistory.