Enum을 JSP 페이지에 노출 시키기
개요
scriptlet은 독이다. scriptlet을 잘쓰고 있는 지인에게 ‘scriptlet은 독이이야’라고 말했다가 미움받았다. 어쨌든 scriptlet을 안쓰고 jsp짜려니까 좀 골때려지는 부분들도 있다. 먼가 방법이 있을까 찾아보니 Spring Interceptor를 이용해서 Enum을 request 스콥에 노출시켜주는 글을 찾았다.
request 스콥에 노출시키는 방법은 다음과 같은 방법이 있을 수 있다.
- ServletFilter
- Spring Interceptor
- Controller
하지만 Enum을 요청마다 매번 request에 넣어주는게 좀 후져 보였다. 저장소를 application 스콥으로 잡고 WAS가 기동할 때 넣어줄 수 있도록 ContextListener로 구현하기로 했다.
예제
다음과 같은 enum 클래스가 있다고 하면:
package kr.pismute
public enum Week {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}
jsp에서 다음과 같이 사용할 수 있다. 사실 applicationSope이란 내장객체라는게 참 촌스럽다. 그냥 application으로 하지 못할 이유라도 있었는지…
${applicationScope.week.MONDAY}
Week라는 클래스 이름은 자바 네이밍 컨벤션에 따라 week으로 바꿔서 넣는다. GoldenWeek였다면 goldenWeek로 바뀐다.
이제 web.xml에 이 ContextListner를 넣는다:
<context-param>
<param-name>enumServletContextConfig</param-name>
<param-value>kr.pismute.Week</param-value>
</context-param>
<listener>
<listener-class>kr.pismute.EnumContextListener</listener-class>
</listener>
Enum에 빈을 추가해서 사용할 수도 있다. Week에 다음과 같이 추가하고:
private Integer day;
public Integer getDay(){
return day;
}
jsp에서 다음과 같이 day 프로퍼티를 사용할 수 있다.
${applicationScope.week.MONDAY.day}
Code
pacakge kr.pismute
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* JSP에서 ENUM 클래스에 접근할 수 있도록 ServletContext에 넣어줍니다.
*
* @author pismute
*
*/
public class EnumContextListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent sce) {
}
public void contextInitialized(ServletContextEvent sce) {
String param = sce.getServletContext().getInitParameter("enumServletContextConfig");
String[] params = param.split(",");
for(String className : params) {
className = className.trim();
this.loadEnum(className, sce.getServletContext());
}
}
/**
* Enum 인스턴스를 찾아서 Map<name, Enum<?>> 맵으로 변환하고
* ServletContext에 넣습니다.
*
* @param className
*/
@SuppressWarnings("unchecked")
private void loadEnum(String className, ServletContext context) {
Map<String, Enum<?>> ret = null;
try {
Class<Enum> clazz = (Class<Enum>)Class.forName(className);
Enum[] enums = clazz.getEnumConstants();
ret = new HashMap<String, Enum<?>>(enums.length);
for(Enum e : enums) {
ret.put(e.name(), e);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
ret = Collections.unmodifiableMap(ret);
context.setAttribute(this.getAlias(className), ret);
}
/**
* 클래스 첫 문자를 소문자로 바꿔서 alias를 만듭니다.
*
* @param className
* @return
*/
private String getAlias(String className) {
String[] token = className.split("\\.");
String alias = token[token.length - 1].trim();
String initial = alias.substring(0, 1);
String suffix = alias.substring(1);
initial = initial.toLowerCase();
alias = initial + suffix;
return alias;
}
}