不厭其煩

Reder’s Blog, experimental version

Posts Tagged ‘jstl

在 JSTL 中取用 Java constants

leave a comment »

以下程式碼來自討論串中。

在 Java 中,我們會使用 public static final String A_CONST  = "const"; 的方式設定常數,但在 JSTL 中無法直接取用。以下是解決方法:

  1. 由於 JSTL 可以取得 Map 或 JavaBean 的值,所以我們可以利用這個特性,建立一個 Class 繼承 HashMap 。然後用 relection 將其中的 fields 放入 Map 中。
    package com.utils;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Class to reveal java constants to JSTL Expression Language
     * Uses reflection to scan the declared fields of a Constants class
     * Adds these fields to the Map.
     * Map is unmodifiable after initialization.
     *
     */
    public class JSTLConstants extends HashMap {
    	private boolean initialised = false;
    
    	public JSTLConstants() {
    		Class c = this.getClass();
    		Field[] fields = c.getDeclaredFields();
    		for (int i = 0; i < fields.length; i++) {
    
    			Field field = fields&#91;i&#93;;
    			int modifier = field.getModifiers();
    			if (Modifier.isFinal(modifier) && !Modifier.isPrivate(modifier))
    				try {
    					this.put(field.getName(), field.get(this));
    				}
    				catch (IllegalAccessException e) {}
    		}
    		initialised = true;
    	}
    
    	public void clear() {
    		if (!initialised)
    			super.clear();
    		else
    			throw new UnsupportedOperationException("Cannot modify this map");
    	}
    
    	public Object put(Object key, Object value) {
    		if (!initialised)
    			return super.put(key, value);
    		else
    			throw new UnsupportedOperationException("Cannot modify this map");
    	}
    
    	public void putAll(Map m) {
    		if (!initialised)
    			super.putAll(m);
    		else
    			throw new UnsupportedOperationException("Cannot modify this map");
    	}
    
    	public Object remove(Object key) {
    		if (!initialised)
    			return super.remove(key);
    		else
    			throw new UnsupportedOperationException("Cannot modify this map");
    	}
    }
    &#91;/sourcecode&#93;</li>
    	<li>然後我們的 Constants Class 再繼承上面的 Class: 
    package com.utils;
    
    import java.util.*;
    public class JSTLConstantsTest extends JSTLConstants {
    
    	public static final String name = "Evnafets";
    	public static final int age = 28;
    	private static final String bad = "bad";
    	public static final String programmingSkill = "Awesome";
    	public static final String[] daysOfTheWeek = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
    	public int temp = 100;
    
    	public static void main(String[] args) {
    		Map m = new JSTLConstantsTest();
    
    		System.out.println("Tee constants are ");
    		for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
    			Map.Entry me = (Map.Entry) it.next();
    			System.out.println(me.getKey() + " = " + me.getValue());
    		}
    	}
    }
    
  2. 那麼在 JSP 頁面上我們就可以這樣取用:
    <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
    <jsp:useBean id="Constants" class="com.utils.JSTLConstantsTest"/>
    <c:out value="${Constants.name}"/>
    <c:out value="${Constants.age}"/>
    <c:forEach var="day" items="${Constants.daysOfTheWeek}">
      <c:out value="${day}"/>
    </c:forEach>
    

在討論串中另有針對無法繼承的 Interface 或 third party class 的改進法,但基本上我想我個人應該用不到,所以就不整理了。

Written by Reder

07/31/2008 at 3:09 下午

張貼於Java

Tagged with , ,