요샌 리액트니 뷰니 해서 JSP를 잘 안 쓰는 추세이긴 하지만 여전히 수많은 SI 프로젝트에서는 1순위로 애용하고 있는 뷰(View)이기 때문에 나름 프로젝트 간에 잘 쓴 것들을 정리하여 올려본다.


1. 파일 확장자만 가져오기

기능을 만들다보면 첨부파일 같은 것을 처리할 때 해당 파일의 이름에서 확장자 부분만 잘라내고 싶거나 실제 파일명이 아닌, PK ID 등을 이용하여 재조합한 파일명을 만들어야할 때 실제 파일명에서 확장자 부분만 잘라내야할 때가 있다.

예전에 쓰던 방식

<c:set var="imgName" value="${v.pkid}_1${fn:substring(v.fileValue, fn:indexOf(v.fileValue, '.'), fn:length(v.fileValue)) }" />

위 소스처럼 예전에는 fn:substring을 이용하여 전체 파일명에서 .의 index를 찾아서 .의 index부터 파일명의 길이 끝부분 index까지만 잘라내었다. 근데 이 방식의 문제점이 파일명에 만약 확장자를 구분짓는 .외에 또다른 .이 들어가있으면 그 부분부터 파일명의 끝 index까지 잘려버린다는 점이다. 그래서 아래와 같이 고쳐쓰고 있다.

예 1) image.name.jpg => name.jpg
예 2) image_name.jpg => .jpg

최근에 고친 방식

<c:set var="fileExt" value="${fn:split(v.fileValue, '.')}" />  
<c:set var="imgName" value="${v.pkid}_1.${fileExt[fn:length(fileExt)-1]}" />

fn:split을 이용하여 .을 기준으로 나누면 그 값들은 배열로 들어가게 된다. 위 소스에선 fileExt는 배열인 것이다. 여기서 imgName의 value에 써둔 것처럼 fileExt의 배열 요소 중 fn:length(fileExt)-1, 즉 맨 끝 값을 가지고 오면 결국 확장자 값이 나오게 된다. 이 방식대로 하면 명확하게 파일 확장자만 가져올 수 있다.

2. c:forEach 역순으로 출력하기

정-말 어쩌다가 한번씩 내가 가져온 리스트의 순서를 반대로 하여 출력해야할 때가 있다. 정말 드물긴 하지만 쓰인 적이 있기 때문에 정리해본다.

<c:forEach var="data" items="${dataList}" varStatus="status">
    ${data.name} - ${data.title}
</c:forEach>

일반적으로 Controller에서 넘긴 list를 JSTL로 출력할 때 위와 같이 작성한다. 그러면 순서대로 잘 나올 것인데 역순으로 출력해야할 경우는 어떻게 해야할까?

아쉽게도 JSTL의 c:forEach 자체엔 뒤집거나 역순으로 출력하는 기능은 없어보이고 조금 코드를 수정하면 별다른 추가 작업 없이도 가능은 하다.

<c:set var="dataListLength" value="${fn:length(dataList)}"/>
<c:forEach var="data" items="${dataList}" varStatus="status">
    ${dataList[dataListLength-status.index].name} - ${dataList[dataListLength-status.index].title}
</c:forEach>

위와 같이 dataList의 길이값을 따로 c:set을 이용하여 변수로 정의하고 그 변수값에서 현재 list의 index값을 빼주면 역순으로 쭉 출력된다. 어려울 거 없이 조금만 생각해보면 바로 나오는 답이다.

3. <c:out value="${}"/>, ${fn:escapeXml}, ${}

<c:out value=${}/>${fn:escapeXml}은 사실상 하는 일은 같다. 문자열의 값에 포함되는 <, >, &, ', " 문자들의 값들을 &lt;, &gt;, &amp;, &#039;, &#034;로 바꿔주는 역할을 한다.

${}은 다들 알다시피 괄호 안의 값을 그대로 출력해준다.

<c:set var="val" value="<strong>strong</strong>"/>

<div>${val}</div>  
<div>${fn:escapeXml(val)}</div>  
<div><c:out value="${val}"/></div>  
<div><c:out value="${val}" escapeXml="false" /></div>

위 소스코드를 실행하면 소스코드 바로 아래의 스크린샷처럼 나온다. 1번 코드는 val변수 그대로를 보여주고 있고 2, 3번 코드는 각각 특수문자들을 치환하여 보여주고 있어서 HTML 태그가 먹지 않고 문자 그대로 보이게 된다. 4번 코드는 c:out내에 있는 escapeXml옵션값을 false로 주어서 1번 코드와 같은 효과를 내고 있다.

보통 보안감사나 시큐어 코딩 가이드 라인을 보면 JSP 내에서 변수는 <c:out/>이나 fn:escapeXml을 이용하여 출력하도록 권고하고 있다. 그래야 의도하지 않은 스크립트 구문(XSS 공격과 같은)이 실행되지 않도록 할 수 있기 때문이다.