2009년 9월 12일 토요일

[FreeMarker] Built-ins for strings

원문 : http://freemarker.sourceforge.net/docs/ref_builtins_string.html

  • substring

FreeMarker 2.3.7 부터 지원

exp?substring(from, toExclusive) 또는 exp?substring(from) 의 형태로 사용

string의 substring. from 은 첫 문자의 인덱스입니다. from 은 0 이상이고, toExclusive 보다 작거나 같아야 합니다. toExclusive 는 부분 문자열의 다음 문자의 인덱스입니다. toExclusive 는 0 이상이고, 문자열 길이보다 작거나 같아야 합니다. toExclusive 를 생략하면 문자열의 길이로 설정됩니다. 정수가 아닌 숫자를 from 이나 toExclusive으로 사용하는 경우 정수 부분만 사용됩니다.



- ${'abc'?substring(0)}
- ${'abc'?substring(1)}
- ${'abc'?substring(2)}
- ${'abc'?substring(3)}

- ${'abc'?substring(0, 0)}
- ${'abc'?substring(0, 1)}
- ${'abc'?substring(0, 2)}
- ${'abc'?substring(0, 3)}

- ${'abc'?substring(0, 1)}
- ${'abc'?substring(1, 2)}
- ${'abc'?substring(2, 3)}

결과

- abc
- bc
- c
-

-
- a
- ab
- abc

- a
- b
- c

  • cap_first

첫 번째 word 의 첫 문자가 대문자인 문자열. word 의 정확한 의미는 word_list built-in 에서 볼 수 있습니다.



${"  green mouse"?cap_first}
${"GreEN mouse"?cap_first}
${"- green mouse"?cap_first}

결과

  Green mouse
GreEN mouse
- green mouse

  • upcap_first

cap_first 의 반대. 첫 word 의 첫 문자가 소문자인 문자열.

  • capitalize

모든 word의 첫 문자가 대문자인 문자열. word 의 정확한 의미는 word_list built-in 에서 볼 수 있습니다.



${"  green  mouse"?capitalize}
${"GreEN mouse"?capitalize}

결과

  Green Mouse
Green Mouse

  • chop_linebreak

끝에 line_break 가 없는 문자열.

  • date, time, datetime

date 값으로 변환된 문자열. 형식에 대한 파라미터를 명시하는 것을 추천합니다.



<#assign test1 = "10/25/1995"?date("MM/dd/yyyy")>
<#assign test2 = "15:05:30"?time("HH:mm:ss")>
<#assign test3 = "1995-10-25 03:05 PM"?datetime("yyyy-MM-dd hh:mm a")>
${test1}
${test2}
${test3}

결과

Oct 25, 1995
3:05:30 PM
Oct 25, 1995 3:05:00 PM

date 가 date_format, time_format, datetime_format 설정에 따라 변환되었다는 것을 유의하십시오. (date 를 string 으로 변환하는 것에 대한 자세한 정보는 string built-in for dates, date interpolations 에서 볼 수 있습니다.) string 을 date 로 변환할 때 사용한 형식은 중요하지 않습니다.

기본 date/time/datetime 형식이 무엇일지 알고 있다면 형식 파라미터를 사용할 필요가 없습니다.

<#assign test1 = "Oct 25, 1995"?date>
<#assign test2 = "3:05:30 PM"?time>
<#assign test3 = "Oct 25, 1995 03:05:00 PM"?datetime>
${test1}
${test2}
${test3}

  • ends_with
문자열이 특정 문자열로 끝나면 true 를 반환합니다. 예를 들어 "redhead"?ends_with("head")는 boolean true 를 반환합니다. "head"?ends_with("head") 역시 true 를 반환합니다.

  • html

html 문자열. 즉, < 는 &lt; 로, > 는 &gt; 로, & 는 &amp; 로, " 는 &quot; 로 치환된 문자열.

안전하게 속성 값을 삽입하고자 한다면, HTML 에서 속성 값을 큰 따옴표로 둘러싸야 한다는 것에 유의하십시오.

<input type=text name=user value="${user?html}">

일반적으로 많은 타이핑을 없애고, escape directive 를 사용함으로써 발생할 수 있는 실수의 가능성을 줄이기 위해, HTML 에서 모든 것에 이  built-in 을 사용하고 싶을 것입니다.

  • groups

matches built-in 의 결과에만 사용됩니다.

  • index_of

특정 문자열이 처음 나타나는 인덱스를 반환합니다. 예를 들어, "abcabc"?index_of("bc") 는 1을 반환합니다. (첫 문자의 인덱스가 0 입을 잊지 마십시오.) 검색을 시작할 인덱스를 지정할 수도 있습니다. "abcabc"?index_of("bc", 2) 는 4를 반환합니다. 두 번째 파라미터의 숫자는 제한이 없습니다. 두 번째 파라미터가 0 보다 작으면, 두 번째 파라미터가 0일 때와 같은 결과를 반환합니다. 두 번째 파라미터가 문자열의 길이보다 크면, 두 번째 파라미터가 문자열의 길이일 때와 같은 결과를 반환합니다. 파라미터가 소수면, 내림한 정수를 사용하여 결과를 반환합니다.

문자열에 첫 번째 파라미터가 존재하지 않으면 -1 을 반환합니다.

  • j_string

Java 언어의 문자열 escaping 규칙에 따라 문자열을 수정합니다. 게다가 Java 언어에 해당하는 escape sequence 가 없는 모든 문자(UCS code point 0x20) 는 UNICODE escape (\uXXXX) 으로 변경됩니다..



<#assign beanName = 'The "foo" bean.'>
String BEAN_NAME = "${beanName?j_string}";

결과

String BEAN_NAME = "The \"foo\" bean.";

  • js_string

JavaScript 언어 문자열 escaping 규칙에 따라 문자열을 변경합니다. 큰 따옴표(") 와 작은 따옴표(') 가 모두 변경됩니다. FreeMarker 2.3.1 부터 > 는 \> 로 치환됩니다. 게다가 JavaScript 에 escape sequence 가 없는 모든 문자 (UCS code point 0x20) 은 16진수 escape (\xXX) 로 치환됩니다. (물론, JavaScript 언어 문자열 syntax 에 따라 백슬래쉬(\) 도 변경되고, line-feed 는 \n 으로 치환됩니다. 등)



<#assign user = "Big Joe's \"right hand\"">
<script>
alert("Welcome ${user?js_string}!");
</script>

결과

<script>
alert("Welcome Big Joe\'s \"right hand\"!");
</script>

  • last_index_of
문자열의 끝에서부터 검색했을 때, 특정 문자열의 인덱스를 반환합니다. 예를 들어, "abcabc"?last_index_of("ab") 는 3을 반환합니다. 검색을 시작할 인덱스를 지정할 수도 있습니다. 예를 들어, "abcabc"?last_index_of("ab", 2) 는 0을 반환합니다. ...
  • length

문자열의 문자 개수
  • lower_case

소문자로 이루어진 문자열

  • left_pad

FreeMarker 2.3.1 부터 지원

파라미터가 1 개면, 문자열의 길이가 파라미터의 값과 같아질 때까지 문자열의 앞에 공백을 삽입합니다. 만약 문자열의 길이와 파라미터와 같거나 파라미터보다 크면 아무 작업도 하지 않습니다.



[${""?left_pad(5)}]
[${"a"?left_pad(5)}]
[${"ab"?left_pad(5)}]
[${"abc"?left_pad(5)}]
[${"abcd"?left_pad(5)}]
[${"abcde"?left_pad(5)}]
[${"abcdef"?left_pad(5)}]
[${"abcdefg"?left_pad(5)}]
[${"abcdefgh"?left_pad(5)}]


결과

[     ]
[ a]
[ ab]
[ abc]
[ abcd]
[abcde]
[abcdef]
[abcdefg]
[abcdefgh]

파라미터가 2 개일 때, 첫 번째 파라미터는 앞에서 언급한 파라미터와 같은 역할을 합니다. 두 번째 파라미터는 문자열의 앞에 삽입할 문자 입니다.



[${""?left_pad(5, "-")}]
[${"a"?left_pad(5, "-")}]
[${"ab"?left_pad(5, "-")}]
[${"abc"?left_pad(5, "-")}]
[${"abcd"?left_pad(5, "-")}]
[${"abcde"?left_pad(5, "-")}]


결과

[-----]
[----a]
[---ab]
[--abc]
[-abcd]
[abcde]

두 번째 파라미터는 문자열이 될 수도 있습니다. 그러면 문자열인 파라미터가 반복하여 삽입됩니다.



[${""?left_pad(8, ".oO")}]
[${"a"?left_pad(8, ".oO")}]
[${"ab"?left_pad(8, ".oO")}]
[${"abc"?left_pad(8, ".oO")}]
[${"abcd"?left_pad(8, ".oO")}]

결과

[.oO.oO.o]
[.oO.oO.a]
[.oO.oOab]
[.oO.oabc]
[.oO.abcd]

두 번째 파라미터는 반드시 길이가 1 이상인 문자열이어야 합니다.

  • right_pad

FreeMarker 2.3.1 부터 지원됩니다.

이 것은 left_pad 와 같지만, 두 번째 파라미터(또는 공백)을 문자열의 앞이 아니라 뒤에 삽입합니다.



[${""?right_pad(5)}]
[${"a"?right_pad(5)}]
[${"ab"?right_pad(5)}]
[${"abc"?right_pad(5)}]
[${"abcd"?right_pad(5)}]
[${"abcde"?right_pad(5)}]
[${"abcdef"?right_pad(5)}]
[${"abcdefg"?right_pad(5)}]
[${"abcdefgh"?right_pad(5)}]

[${""?right_pad(8, ".oO")}]
[${"a"?right_pad(8, ".oO")}]
[${"ab"?right_pad(8, ".oO")}]
[${"abc"?right_pad(8, ".oO")}]
[${"abcd"?right_pad(8, ".oO")}]

결과

[     ]
[a ]
[ab ]
[abc ]
[abcd ]
[abcde]
[abcdef]
[abcdefg]
[abcdefgh]

[.oO.oO.o]
[aoO.oO.o]
[abO.oO.o]
[abc.oO.o]
[abcdoO.o]

  • contains

FreeMarker 2.3.1 부터 지원됩니다.

파라미터가 문자열에 있으면 true 를 리턴합니다.



<#if "piceous"?contains("ice")>It contains "ice"</#if>

결과

It contains "ice"

  • matches

"power user" built-in 입니다. regular expression(정규식) 을 모르면 무시해 주세요.

FreeMarker 2.3.1 부터 지원됩니다.

Java 2 플랫폼 1.4 이상의 버전을 사용할 때만 동작합니다.

이 built-in 은 문자열이 패턴에 해당하는지 판단합니다. 그리고 해당하는 부분 문자열의 리스트를 반환합니다. 반환되는 값은 multi-type 값입니다.

Boolean: 문자열이 패턴과 정확하게 일치하면, true. 아니면, false. 예를 들어, "fooo?matches('fo*') 는 true 지만, "fooo bar"?matches('fo*') 는 false 입니다.



<#if "fxo"?matches("f.?o")>Matches.<#else>Does not match.</#if>

<#assign res = "foo bar fyo"?matches("f.?o")>
<#if res>Matches.<#else>Does not match.</#if>
Matching sub-strings:
<#list res as m>
- ${m}
</#list>


결과

Matches.

Does not match.
Matching sub-strings:
- foo
- fyo

정규식이 groups (괄호) 를 포함하면, groups built-in 으로 접근할 수 있습니다.

<#assign res = "aa/rx; ab/r;"?matches("(\\w[^/]+)/([^;]+);")>
<#list res as m>
- ${m} is ${m?groups[1]} per ${m?groups[2]}
</#list>

결과

- aa/rx; is aa per rx
- ab/r; is ab per r

matches 는 생략 가능한 두 번째 파라미터 flags 를 허용합니다. 항상 정규식을 사용하기 때문에 flag r 은 지원되지 않는다는 것을 유의하십시오.
  • number

숫자로 변환된 문자열. number 는 FTL 에서 직접 숫자를 명시했을 때와 같은 형식이어야 합니다. 즉, 숫자들 사이에 . 이 있는 locale independent form 이어야 한다는말입니다. 추가적으로 이 built-in 은 몇 가지 특정 표현을 인식합니다.(예: "1.23E6", "1.5e-8").

알려진 문제점: Java2 플랫폼 1.3 이전의 버전을 사용하면 이 built-in 은 숫자 앞의 + 와 과학적인 표현을 인식하지 못합니다.

  • replace

문자열의 모든 특정 부분 문자열을 다른 문자열로 치환합니다. 단어를 다루지는 않습니다.



${"this is a car acarus"?replace("car", "bulldozer")}

결과

this is a bulldozer abulldozerus

치환은 왼쪽에서 오른쪽으로 진행됩니다.

${"aaaaa"?replace("aaa", "X")}

결과

Xaa 

첫 번째 파라미터가 길이가 0인 문자열이면, 문자와 문자 사이에 두 번째 파라미터가 삽입됩니다. 예를 들어, "foo"?replace("", "|") 는 "|f|o|o|" 입니다.

replace 는 생략가능한 세 번째 파라미터인 flags parameter 를 허용합니다.

  • rtf

Rich text(RTF text) 인 문자열. 즉, \ 가 \\ 로 치환되고, { 가 \{ 로 치환되고, } 가 \} 로 치환되는 문자열.

  • url

FreeMarker 2.3.1 부터 지원됩니다.

URL escaping 을 거친 문자열. 모든 US-ASCII 가 아닌 문자와 URL 예약어가 %xx 로 치환되는 것을 의미합니다.



<#assign x = 'a/b c'>
${x?url}

결과(US-ASCII compatible charset 을 사용했다고 가정)

a%2Fb%20c

Note that it escapes all reserved URL characters (/, =, &, ...etc), so this encoding can be used for encoding query parameter values, for example:

<a href="foo.cgi?x=${x?url}&y=${y?url}">Click here...</a>  

Note

Above no HTML encoding (?htm) was needed, because URL escaping escapes all reserved HTML characters anyway. But watch: always quote the attribute value, and always with normal quotation mark ("), never with apostrophe quotation mark ('), because apostrophe quotation mark is not escaped by the URL escaping.

To do URL escaping a charset must be chosen that will be used for calculating the escaped parts (%XX). If you are HTML page author and you don't really understand this, don't worry: the programmers should configure FreeMarker so that it uses the proper charset by default (programmers: see more below...). If you are a more technical minded user, then you may want to know that the charset used is specified by the url_escaping_charset setting, that can be set in template execution time (or, preferably, earlier by the programmers). For example:

<#--
This will use the charset specified by the programmers
before the template execution has started.
-->
<a href="foo.cgi?x=${x?url}">foo</a>

<#-- Use UTF-8 charset for URL escaping from now: -->
<#setting url_escaping_charset="UTF-8">

<#-- This will surely use UTF-8 charset -->
<a href="bar.cgi?x=${x?url}">bar</a>

Furthermore, you can explicitly specify a charset for a single URL escaping as the parameter to the built-in:

<a href="foo.cgi?x=${x?url('ISO-8895-2')}">foo</a>  

If the url built-in has no parameter, then it will use the charset specified as the value of the url_escaping_charset setting. This setting should be set by the software that encloses FreeMarker (e.g. a Web application framework), because it is not set (null) by default. If it is not set, then FreeMarker falls back using the value of the output_encoding setting, which is also not set by default, so it is again the task of the enclosing software. If the output_encoding setting is not set either, then the parameterless url built-in can't be executed, and it will cause execution time error. Of course, the url built-in with parameter always works.

It's possible to set url_escaping_charset in the template with the setting directive, but it is bad practice, at least in true MVC applications. The output_encoding setting can't be set with the setting directive, so that's surely the task of the enclosing software. You may find more information regarding this here...


  • split

한 문자열을 여러 문자열로 나눌 때 사용됩니다.



<#list "someMOOtestMOOtext"?split("MOO") as x>
- ${x}
</#list>

결과

- some
- test
- text

모든 분리자가 새로운 아이템 전에 사용된다고 가정하고 있다는 점에 유의하십시오.

<#list "some,,test,text,"?split(",") as x>
- "${x}"
</#list>

결과

- "some"
- ""
- "test"
- "text"
- ""

  • starts_with

특정 문자열로 시작하면 true 를 반환합니다. 예를 들어, "redhead"?starts_with("red") 는 boolean true 를 반환합니다. "red"?starts_with("red") 도 true 를 반환합니다.

  • string(when used with a string value)

아무 일도 하지 않고 현재의 문자열을 반환합니다. 예외는 값이 여러 가지 형태일 때 결과 값이 단순한 문자열이 된다는 것입니다. multi-typing 의 artifact 를 방지하기 위해 활용될 수 있습니다.

  • trim

처음과 끝에 공백이 없는 문자열.



(${"  green mouse  "?trim})

결과

(green mouse)

  • upper_case

대문자로만 이루어진 문자열. 예를 들어, "GrEen MoUsE" 는 "GREEN MOUSE" 가 됩니다.

  • word_list

문자열의 모든 word 의 리스트. word 의 순서는 문자열에 나타나는 순서입니다. word 는 white-space 가 아닌 모든 문자의 연속입니다.



<#assign words = "   a bcd, .   1-2-3"?word_list>
<#list words as word>[${word}]</#list>

결과

[a][bcd,][.][1-2-3]

  • xhtml

XHTML 텍스트인 문자열. 즉, < 는 &lt; 로, < 는 &gt; 로, & 는 &amp; 로, " 는  &quot; 로, ' 는 &#39; 로, ' 는 &apos; 로 치환된 문자열.

이  built-in 과 xml built-in 의 차이는 xhtml built-in 은 ' 을 &apos; 대신 &#39 ;  로 치환하여 사용한다. 왜냐하면 오래된 몇 몇 브라우저는 &apos; 를 바르게 처리하지 못하기 때문이다.
  • xml

XML 텍스트인 문자열. 즉, < 는 &lt; 로, < 는 &gt; 로, & 는 &amp; 로, " 는  &quot; 로, ' 는 &apos; 로, ' 는 &apos; 로 치환된 문자열.
  • Common flags

[freemarker]주요 BI

freemarker reference : http://freemarker.sourceforge.net/docs/index.html
Built-in Reference : http://freemarker.sourceforge.net/docs/ref_builtins.html

레퍼런스 문서 정말 잘 되있다.
필요한건 위의 링크 타고 보면 되고 그외
필요하고 자주 쓰는 것만 따로 뽑았다.

list 관련

_index
- for문(<#list ..>) 돌리다 보면 이게 몇번째인지 궁금할 수 있다.
  한 row에 4개씩 보여 줘야 한다든지 할때 alias로 할당된 변수에 "_index"붙이면
  sequence를 구할 수 있다.  
- 예 :
   <#list array as output>
        ${output_index}
   </#list>

_has_next
- 배열값 중에 다음 값이 존재하는지 여부를 반환한다.
- 예 :
   <#list array as output>
        ${output_index}
        <#if output_has_next></tr></#if>
   </#list>


문자열 관련 

[x...y]
- 문자열의 일정 범위를 자를때 사용하는 함수
- 예 :
-----------------------------
  ${hello}<br>
  ${hello[1..4]}<br>
  ${hello?substring(1,4)}<br>
-----------------------------
null님 안녕하세요
ull님
ull
-----------------------------
substring과는 조금 다른 결과를 확인할 수 있다.


null 처리 관련

?has_content
- 배열값이 null이 아니고 1개 이상인지 체크하는 함수
  ?exists와 ?size>0 두가지 기능을 포함한다.
- 예 :
 <#if array?has_content>
    ... 처리
 </#if>

?exists
- null 체크
- 예 :
 <#if user?exists>
    ... 처리
 </#if>

?default
- 오브젝트의 값이 null인 경우 입력된 사용자값을 반환한다.
- 예 :
  ${user?default("")}


!"대체값"
- 만약 값이 없다면 ! 값 뒤에 정의된 값이 할당된다.
- 예 :
${hello!'안녕하세요'}
이렇게 하면 값이 없으면 "안녕하세요"가 찍힌다.

??
- null 여부에 따라 true, false 반환
- 예 :
<#if user??>${user}<#else>사용자</#if>
${user!"사용자"} 이것과 동일한 결과를 반환한다.

[freemarker]boolean 값 처리


    @RequestMapping("/test/test1.gs")
    public ModelAndView test1(@ModelAttribute("kkaok") TestDto testDto, Test2Dto test2Dto, BindingResult errors) throws Exception {
        ModelAndView mav = new ModelAndView("/test/test1");
        boolean testBoolean = true;
        mav.addObject("testBoolean", testBoolean);
        return mav;
    }

서버단에서 아래처럼 값을 내려 준다고 할때

${testBoolean}

이렇게 하면 에러가 난다.

${testBoolean?string}


이런식이어야 하는데 조건에 따라 다른 값을 보여 줘야 한다면?

${testBoolean?string("니가 맞아^^","내가 틀릴줄 알았다!!!")}


굳이 조건문이 들어 갈 필요가 없다.


그외
$(booleaValue?string) 이렇게 하면 기본 값은 true, false이다. 두개의 값은 comma로 구분되며
이 기본 값을 바꿀 수도 있다.
<#setting boolean_format = "good,bad">

이렇게 상단에 설정을 해 주고
${testBoolean?string} 이렇게 하면 화면에 보이는 결과는 good이 찍히게 된다.
전체 페이지에 필요하다면 공통으로 뽑아서 include하면된다.
전체에 쓰는데 굳이 include하고 싶지 않다면 시스템 설정에 추가해주면된다.

 <!-- freemarker config -->
 <bean
  class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  <property name="templateLoaderPath" value="/WEB-INF/templates" />
  <property name="freemarkerSettings">
   <props>
    <prop key="number_format">###.###</prop>
    <prop key="date_format">yyyy-MM-dd</prop>
    <prop key="boolean_format">yes,no</prop>
      </props>
  </property>
 </bean>

[freemarker] null처리

ftl파일에 아래 같은 내용을 코딩한다.

${hello}

hello에 값이 있다면 그 값을 뿌려준다. ^^
정상~~~

에러상황 : hello 자체를 서버단에서 내려 주지 않았거나 값이 null이라면?
 
freemarker에서는 request에 담긴 값을 map에 담아서 내려주는데 값이 없으면 아예 담지를 않는다.
따라서 key가 없으니 에러가 날 수 밖에 없다.

The problematic instruction:
----------
==> ${x} [on line 6, column 1 in test/test1.ftl]
----------

이때는 아래처럼 처리하면 된다.

${hello!'안녕하세요'}

이렇게 하면 값이 없으면 "안녕하세요"가 찍힌다.

그외 추가

<#if user??><h1>Welcome ${user}!</h1><#else>사용자</#if>
${user!"사용자"}

두개의 결과물은 같다 ^^

[spring] 파일업로드 크기 제한.

스프링에서 파일 업로드시 업로드되는 파일을 크기를 appilicationContext.xml 설정파일로서 제한 할 수가 있다.

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- one of the properties available; the maximum file size in bytes --> <property name="maxUploadSize"> <value>5242880</value> </property> <property name="defaultEncoding"> <value>EUC-KR</value> </property> </bean>

  위와 같이 maxUploadSize 를 설정하므로서 제한이 가능하며, 이 제한을 넘어가면 org.springframework.web.multipart.MaxUploadSizeExceededException 이 발생된다. 이때의 문제는 해당에러가 스프링단에서 발생되므로 해당 내용이 Controller까지 전달되지 못하며, 그로인해 Exception을 제어 할 수 없게 된다.

  이 문제는 아래와 같이 exceptionResolver를 설정해주므로서 제어 가능하다.

<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException"> /error/imgUploadErr </prop> </props> </property> </bean>

  위 경우엔 MaxUploadSizeExceededException 이 발생하면 /error/ 경로의 imgUploadErr라는 view 페이지로 forward 된다는 의미이다. 이 페이지를 통해 적절한 에러 메시지를 노출시켜주므로서 파일업로드시 용량제한으로 발생되는 Exception을 제어 할 수 있게 된다.

[freemaker] jsp freemaker tag

freemarker 설명 및 기본 예제

# 이 문서는 오라클클럽에서 작성하였습니다.
# 이 문서를 다른 블로그나 홈페이지에 게재하실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
# 출처 : http://wiki.oracleclub.com/pages/viewpage.action?pageId=1343682&



1 FreeMarker 란?

  • 프리마커는 자바 서블릿을 위한 오픈소스 HTML 템플릿 엔진이다.
  • 프리마커에서는 HTML을 템플릿으로 저장하는데 이들은 결국 템플릿 객체로 컴파일 된다.
  • 이 템플릿 객체들은 서블리셍서 제공하는 데이터들을 이용하여 HTML을 동적으로 생성한다.
  • 프리마커 객체들은 서블릿에서 제공하는 데이터들을 이용하여 HTML을 동적으로 생성한다.
    [*.java]Servlet \+Template[*.ftl] = [*.html]Output

2 FreeMarker 구조

  • FreeMarker는 표현의 결과물을 HTML(템플릿)로 관리하고 여기에 자바 객체를 연결하여 최종적인 결과를 만들어낸다.

3 FreeMarker 셋팅

3.1 다운로드

3.2 설치

  • freemarker.jar 파일을 WEB-INF/lib 안에 넣는다.
  • ecilpse에서는 프로젝트 마다 lib안에 import 시킨다.

3.3 Java 코딩시

import freemarker.template.*;
  • FreemarkerServlet를 extends 한 후 Java coding 해주면 된다.

4 FreeMaker 문법

  • FreeMarker의 메뉴얼 : http://www.freemarker.org/docs/
    FTL tag 
    <# > 
    
    
    주석 
    <#--주석달기--> 
    
    
    반복문 
    1. 
    <#list [Object code에서 key값 ]  as  [별칭할 값]> 
     
    2. for(int i=0;i<10;i++)
    <#list  1..10  as i > 
          ${i}
       <#assign i=i+1?int>
     
    3. 사이즈를 알고 싶을때.. Key 값이 list 인 경우
     
    <#assign size=list?size>
     
    4. 다른 변수로 정의하고 싶을때에는 
    <#setting [새로]=[기존]>
    
     
    5. 변수선언 
    
    <#assign x=0>   <#--x에 0를 할당해 준것이다. --> 
    x값을 출력하고자 할때 --> ${x} 
    
    
    6. <#macro green> 
    "<@green>"이런식으로 쓴다. 
    주로 변하지 않는 변수를 이렇게 선언해서 쓴다. 
     
    7. 조건문 
    <#if> 
     
    8. int형으로 선언해 주고 싶은때에는
    <#assign x=0 ? int>
    
    

5 FreeMarker 예제

5.1 TLD 파일

  • fmtag.tld (WEB-INF 아래 위치)
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <!DOCTYPE taglib
          PUBLIC "-Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
          "http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd">
    <taglib>
      <tlibversion>2.0<.tlibversion>
      <jspversion>1.1</jspversion>
      <shortname>FreeMarker JSP Support</shortname>
    
      <tag>
       <name>template</name>
       <tagclass>freemarker.ext.jsp.FreemarkerTag</tagclass>
       <bodycontent>tagdependent</bodycontent>
       <info>Allow evaluation of FreeMarker templates inside JSP</info>
       <attribute>
        <name>cashing</name>
        <required>false</required>
       </attribute>
      </tag>
    </taglib>
    

5.2 java 파일

  • SimpleBean.java (WEB-INF/classes/freemarker/examples/jsp)
  • Custom Tag 수행을 위한 Tag Handler Class
    package freemarker.examples.jsp;
    
    public class SimpleBean
    {
      private static String[] arr = {"a","b","c","d"};
      private String theString = "Hello from " + toString();
    
      public void setString(String foo)
      {
        theString = foo;
      }
    
      public String getString()
      {
        return theString;
      }
    
      public String[] getArray()
      {
        return arr;
      }
    }
    

5.3 jsp 파일

  • freemarker2.jsp (View 파일)
    <%@ page contentType="text/html; charset=euc-kr" %>
    <%@ taglib uri="/WEB-INF/fmtag.tld" prefix="fm" %>
    
    <jsp:useBean id="mybean" class="freemarker.examples.jsp.SimpleBean"/>
    <jsp:useBean id="mybeanreq" class="freemarker.examples.jsp.SimpleBean" scope="request" />
    
    <fm:template>
    <html>
    <body>
     <h1>FreeMarker JSP example</h1>
     <hr>
     <p>JSP 페이지</p>
    
     <#assign mybean = page.mybean>
     <#assign mybeanreq = request.mybeanreq>
    
     <p>page : ${mybean.string}
     <#list mybean.array as item>
      <br>${item}
     </#list>
    
     <p><b>Note:</b>
    </body>
    </html>
    </fm.template>
    


Freemaker를 쓰다가 잘 생기는 오류...[펌글]


태생이 JSP 개발자라 그런지 원치는 않았지만 Spring Framework + Sitemesh + Freemaker 를 이용한 프로젝트에 참여후 SM 일을 보고 있습니다.

JSP때도 오류(버그)는 발생하는 일이지만 Freemaker의 경우 좀 더 자주 발생하는 듯 합니다.

Freemaker를 쓰며 자주 발생하는 에러를 모아봤습니다.

1. Null 체크를 하지 않는 경우

특정 객체에 담긴 값을 꺼내 쓰는 경우, 주로 DTO에 담긴 값을 꺼내 쓰는 경우가 많습니다., Null값을 체크하지 않는 경우가 많습니다. JSP 개발시엔 그래도 많은 사람들이 경험을 통해 객체의 Null 여부를 체크하는 경우가 많지만 Freemaker를 쓰면서는 이걸 빼먹는 경우가 많습니다.

객체의 담긴 값을 쓸때는 다음의 Null 값 체크를 꼭 하셔야 합니다.

<#if myObject.value?exists>
    //.... 뭔가를 수행 ....
</#if>

2. int 또는 long 등의 Number 타입의 값을 사용하는 경우

제가 Freemaker 전문은 아니라 이게 Default인지 설정인지는 모르겠으나, 찾아봐야겠네요. 이번기회에..., Number 타입의 값이 1000을 넘어서면 자동으로 콤마(,)가 찍힙니다. 1,000 이런식으로 말이죠. 이때 테이블이나 id값등을 숫자로 사용하는 경우 해당 값에 콤마가 찍힌채로 넘어가게 되어 NumberFormatException 등이 발생하거나 테이블 SELECT 시 값이 나오지 않는 경우가 발생합니다.

차라리 에러라도 나면 찾으련만 단순히 SELECT 값이 나오지 않는 경우 처음엔 원인을 찾느라 시간을 많이 허비했습니다.(요즘은 딱 보면... 감이 오긴 합니다.)

이때는 ${myObject.value?string("##0")} 혹은 ${myObject.value?string.number} 등으로 콤마를 표시하지 않을 수 있습니다.

확인 해봐야 겠지만 설정으로 한번에 고칠 수 있다면 편하겠죠. 하지만 장점도 있습니다. 쇼핑몰 같은 경우 빈번한 가격표시를 해야할때 Number 타입의 값을 콤마를 찍지 않고도 간편히 표시할 수 있다는 점이죠.


약 2-3달여 SM 업무를 하며 많이 발생한 오류가 저 두가지 인듯 합니다. 특히 10여명이 넘는 많은 인원들이 빠른시간내에 개발해야하는 IT 프로젝트 특성상 한두개 테스트 하는 경우엔 값이 나오니 빼놓는 경우가 많은 듯 합니다.