시작

  1. Configuration 인스턴스 생성
  2. Data-model 생성
    • String
    • Number
    • Boolean
    • java.util.Date
    • java.util.Map
    • Custom Beans
  3. Template 인스턴스 얻기
  4. Template과 data-model 머지

Data-model

Scalar

각 스칼라 타입은 TemplateTypeNameModel 인터페이스에 해당한다

Boolean, Number, String, Date-like(Date, Time, Date-time)

Container

Hash

↓ java

interface TemplateHashModel extends TemplateModel { TemplateModel get(String key) boolean isEmpty() }

Sequence

↓ java

interface TemplateSequenceModel extends TemplateModel { TemplateModel get(int index) int size() }

Collection

↓ java

interface TemplateCollectionModel extends TemplateModel { TemplateModelIterator iterator() }

Method

↓ java

interface TemplateMethodModelEx extends TemplateMethodModel { Object exec(List arguments) }

Object Wrapper

interface ObjectWrapper

  1. TemplateModel wrap(Object obj)

interface ObjectWrapperAndUnwrapper extends ObjectWrapper

  1. static final Object CANT_UNWRAP_TO_TARGET_CLASS
  2. unwrap은 가능하지만, 결과물이 타깃 클래스 인스턴스가 아닐 수 있음을 표시. 아니면 null

  3. Object unwrap(TemplateModel tm)
  4. unwrap 실패의 의미로 null을 반환하지 말 것

  5. Object tryUnwrapTo(TemplateModel tm, Class targetClass)
  6. targetClass가 Object.class가 아닌 경우, 변환이 안 될 것 같으면 CANT_UNWRAP_TO_TARGET_CLASS 반환

class DefaultObjectWrapper extends BeansWrapper

FreeMarker에서 기본으로 사용하는 ObjectWrapper. Configuration#getDefaultObjectWrapper 또는 DefaultObjectWrapperBuilder#build로 획득

Configuration

  1. Shared variable
  2. 모든 템플릿이 공유하는 변수(함수와 directive도 변수임을 상기) 설정. Configuration#setSharedVariable

  3. Setting
  4. locale, number_format, default_encoding, template_exception_handler, date_format, time_format, datetime_format, time_zone, url_escaping_charset 등setSetting-String-String-

  5. Template loading
    • 템플릿 로더 설정
      • Configuration#setDirectoryForTemplate : 파일 시스템 상의 기본 디렉터리 지정
      • Configuration#setClassForTemplateLoading
        Configuration#setServletContextForTemplateLoading
      • 클래스 로딩과 같은 매커니즘으로 템플릿을 가져오고자 할 때 사용. jar로 웹앱을 배치한 경우 유용
        setServletContextForTemplateLoading(servletContext, path) == setTemplateLoader(new WebappTemplateLoader(sctxt, path))

      • Configuration#setServletContextForTemplateLoading
      • ServletContext#getResource를 이용해 템플릿 로드. 압축 상태의 war에서도 잘 동작. WEB-INF/web.xml에 *.ftl등 템플릿 확장자 설정해야 함

      • Configuration#setTemplateLoader
      • 직접 TemplateLoader를 구현했거나, 템플릿 로더의 설정을 변경하여 이용해야 하는 경우 이용
        * 이미 URLTemplateLoader이 구현돼있으니 괜한 뻘짓할 필요 없다

    • 여러 장소에서 로드
    • Configuration#setTemplateLoader(new MultiTemplateLoader(new TemplateLoader[] { loader1, loader2, ... }))

  6. Template caching
  7. 로드된 템플릿은 캐시된다. 기본 갱신 주기는 5초며, Configuration으로 설정 가능. 클래스 로더를 이용하는 경우 갱신 파악에 문제가 있을 수 있다
    getTemplate을 호출하면 캐시에 저장되고, 템플릿 파일이 삭제되면 캐시에서도 삭제된다
    기본적으로 MruCacheStorage가 이용된다

    • MruCacheStorage : strong part + soft part 2단계 캐싱
    • Strong part : JVM에 의해 정리되지 않는 캐시
    • Soft part : JVM에 의해 정리될 수 있는 캐시
    • 디폴트 옵션은 strong 0, soft Integer.MAX_VALUE
    • 변경하려면 Configuration#setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250)) 또는 Configuration#setSetting(Configuration.CACHE_STORAGE_KEY, "strong:20, soft:250")

보안 권한

보안 설정한 JVM으로 실행하는 경우 권한을 부여해야 한다