You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Bryan Hunt <ad...@revoltingdigits.com> on 2004/07/07 20:01:19 UTC
using Constants from JSTL .....
Ok, tearing my hair out right now and extremely confused.
If you look at the Java Technology Forums you will see a rather nice
little pattern that
someone called evnafets has created, it allows you to use a single
Constants class
both in your Actions and in your JSP pages ...
It uses reflection to add it's static final members to a map which can
then be accessed by JSTL like so
<c:out value="${Constants.FOR_RENTAL_PROPERTIES_SELECTION}"/>
The address is
http://forum.java.sun.com/thread.jsp?forum=45&thread=508847&message=2415101
<http://forum.java.sun.com/thread.jsp?forum=45&thread=508847&message=2415101>
This works with a lot of stuff but the jstl and struts tags seem to be a
little inconsistent in their behaviors.
For example this works ...
snip=
<html:select property="propertyTypes" multiple="true">
<html-el:optionsCollection
name="${Constants.PROPERTY_TYPES_SET}" value="id" label="name"/>
</html:select>
=snip
But for some reason ( my stupidity and the time of the evening ) I
cannot get this to work.
snip=
<c:set var="emailNotifications"
value="${scope['Constants.EMAIL_NOTIFICATIONS']"></c:set>
<c:out value="${emailNotifications.priceRangeStart}"/>
=snip
or like this
snip=
<c:set var="emailNotifications"
value="${scope[${Constants.EMAIL_NOTIFICATIONS}]"></c:set>
<c:out value="${emailNotifications.priceRangeStart}"/>
=snip
I'm starting to feel like I'm back in my Perl days again .... Is there a
way that I can dereference these
beans or do I have to use sloppy string literals in my jstl code ?
Any suggestions or am I just stupid to want to do this ?
--b
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: using Constants from JSTL .....
Posted by Kris Schneider <kr...@dotech.com>.
It's not so bad, really ;-). For some additional background, here are a few
older messages from struts-user and taglibs-user:
http://marc.theaimsgroup.com/?l=struts-user&m=103790677413408&w=2
http://marc.theaimsgroup.com/?l=struts-user&m=105777660215673&w=2
http://marc.theaimsgroup.com/?l=taglibs-user&m=105889207116316&w=2
Here's a slightly different approach:
package com.dotech.util;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class ConstantBean implements Serializable {
private Map constants;
public ConstantBean() {
super();
}
public void setClassName(String className) throws ClassNotFoundException,
IllegalAccessException {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
loader = getClass().getClassLoader();
if (loader == null) {
loader = ClassLoader.getSystemClassLoader();
}
}
Class clazz = loader.loadClass(className);
Field[] allFields = clazz.getDeclaredFields();
int numFields = allFields.length;
Map propMap = new HashMap(numFields);
for (int i = 0; i < numFields; i++) {
Field f = allFields[i];
int mods = f.getModifiers();
if (Modifier.isPublic(mods) &&
Modifier.isStatic(mods) &&
Modifier.isFinal(mods)) {
String name = f.getName();
Object value = f.get(null);
propMap.put(name, value);
}
}
this.constants = Collections.unmodifiableMap(propMap);
}
public Map getConstants() {
return this.constants;
}
}
Which can be used in a page like this:
<%@ page contentType="text/plain" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<jsp:useBean id="responseConstants" class="com.dotech.util.ConstantBean">
<jsp:setProperty name="responseConstants"
property="className"
value="javax.servlet.http.HttpServletResponse"/>
</jsp:useBean>
SC_INTERNAL_SERVER_ERROR: <c:out
value="${responseConstants.constants.SC_INTERNAL_SERVER_ERROR}"/>
Quoting Bryan Hunt <ad...@revoltingdigits.com>:
> Uh oh, I just realised that is the exact same as mine just implimented
> differently.
>
> <c:out value="${CONSTANTS.WHATEVER)"/>
>
> Will output the string value but will not be able to be used to resolve
> the bean by that
> name.
>
> I'm giving up on JSTL constants. Nice idea ... but too expensive on my
> hairline.
>
> --b
>
> Rick Reumann wrote:
>
> > On Wed, 07 Jul 2004 20:12:02 +0200, Bryan Hunt
> > <ad...@revoltingdigits.com> wrote:
> >
> >> And it works fine, but really what I am trying to get here is the
> >> value of using Constants in
> >> both my Actions and my ( JSTL based ) jsp's.
> >
> >
> > You need to have all your Constants in a Map that is in application
> > scope. Kris Schneider posted this great piece of code to add to your
> > Constants file to return all your constants as a Map. At app start up
> > I have a servlet that does several things, one of which call the
> > properties method to put all the stuff in a Map and then you can just
> > put that in scope:
> >
> >
> > //in some servlet at startup:
> > ServletContext context = contextEvent.getServletContext();
> > context.setAttribute("CONSTANTS", UIConstants.getConstantsMap());
> >
> >
> > (Below you don't need to do like I have. I had other reasons to do it
> > this way at the time. But just provide the getConstantFieldsAsMap()
> > method )
> >
> > //example class: UIConstants
> >
> > private static Map constantsMap;
> > static {
> > constantsMap = getConstantFieldsAsMap(UIConstants.class);
> > }
> >
> > public static Map getConstantsMap() {
> > return constantsMap;
> > }
> >
> > //all your constants:
> > public final static String WHATEVER = "whatever";
> >
> > //this does the work.. thanks Kris
> > private static Map getConstantFieldsAsMap(Class cls) {
> > Map propMap = null;
> > try {
> > Field[] allFields = cls.getDeclaredFields();
> > int numFields = allFields.length;
> > propMap = new HashMap(numFields);
> > for(int i = 0; i < numFields; i++) {
> > Field f = allFields[i];
> > int mods = f.getModifiers();
> > if(Modifier.isPublic(mods) && Modifier.isStatic(mods) &&
> > Modifier.isFinal(mods)) {
> > String name = f.getName();
> > Object value = f.get(null);
> > log.debug("Putting name = " + name + " and value=" +
> > value + " into propMap");
> > propMap.put(name, value);
> > }
> > }
> > } catch(IllegalAccessException ie) {
> > log.error("Problem loading constantFieldsAsMap " + ie);
> > }
> > return Collections.unmodifiableMap(propMap);
> > }
> >
> > //end class
> >
> >
> > Now in JSP you can just do:
> >
> > <c:out value="${CONSTANTS.WHATEVER)"/>
--
Kris Schneider <ma...@dotech.com>
D.O.Tech <http://www.dotech.com/>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: using Constants from JSTL .....
Posted by Bryan Hunt <ad...@revoltingdigits.com>.
Uh oh, I just realised that is the exact same as mine just implimented
differently.
<c:out value="${CONSTANTS.WHATEVER)"/>
Will output the string value but will not be able to be used to resolve
the bean by that
name.
I'm giving up on JSTL constants. Nice idea ... but too expensive on my
hairline.
--b
Rick Reumann wrote:
> On Wed, 07 Jul 2004 20:12:02 +0200, Bryan Hunt
> <ad...@revoltingdigits.com> wrote:
>
>> And it works fine, but really what I am trying to get here is the
>> value of using Constants in
>> both my Actions and my ( JSTL based ) jsp's.
>
>
> You need to have all your Constants in a Map that is in application
> scope. Kris Schneider posted this great piece of code to add to your
> Constants file to return all your constants as a Map. At app start up
> I have a servlet that does several things, one of which call the
> properties method to put all the stuff in a Map and then you can just
> put that in scope:
>
>
> //in some servlet at startup:
> ServletContext context = contextEvent.getServletContext();
> context.setAttribute("CONSTANTS", UIConstants.getConstantsMap());
>
>
> (Below you don't need to do like I have. I had other reasons to do it
> this way at the time. But just provide the getConstantFieldsAsMap()
> method )
>
> //example class: UIConstants
>
> private static Map constantsMap;
> static {
> constantsMap = getConstantFieldsAsMap(UIConstants.class);
> }
>
> public static Map getConstantsMap() {
> return constantsMap;
> }
>
> //all your constants:
> public final static String WHATEVER = "whatever";
>
> //this does the work.. thanks Kris
> private static Map getConstantFieldsAsMap(Class cls) {
> Map propMap = null;
> try {
> Field[] allFields = cls.getDeclaredFields();
> int numFields = allFields.length;
> propMap = new HashMap(numFields);
> for(int i = 0; i < numFields; i++) {
> Field f = allFields[i];
> int mods = f.getModifiers();
> if(Modifier.isPublic(mods) && Modifier.isStatic(mods) &&
> Modifier.isFinal(mods)) {
> String name = f.getName();
> Object value = f.get(null);
> log.debug("Putting name = " + name + " and value=" +
> value + " into propMap");
> propMap.put(name, value);
> }
> }
> } catch(IllegalAccessException ie) {
> log.error("Problem loading constantFieldsAsMap " + ie);
> }
> return Collections.unmodifiableMap(propMap);
> }
>
> //end class
>
>
> Now in JSP you can just do:
>
> <c:out value="${CONSTANTS.WHATEVER)"/>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: using Constants from JSTL .....
Posted by Rick Reumann <st...@reumann.net>.
On Wed, 07 Jul 2004 20:12:02 +0200, Bryan Hunt <ad...@revoltingdigits.com>
wrote:
> And it works fine, but really what I am trying to get here is the value
> of using Constants in
> both my Actions and my ( JSTL based ) jsp's.
You need to have all your Constants in a Map that is in application scope.
Kris Schneider posted this great piece of code to add to your Constants
file to return all your constants as a Map. At app start up I have a
servlet that does several things, one of which call the properties method
to put all the stuff in a Map and then you can just put that in scope:
//in some servlet at startup:
ServletContext context = contextEvent.getServletContext();
context.setAttribute("CONSTANTS", UIConstants.getConstantsMap());
(Below you don't need to do like I have. I had other reasons to do it this
way at the time. But just provide the getConstantFieldsAsMap() method )
//example class: UIConstants
private static Map constantsMap;
static {
constantsMap = getConstantFieldsAsMap(UIConstants.class);
}
public static Map getConstantsMap() {
return constantsMap;
}
//all your constants:
public final static String WHATEVER = "whatever";
//this does the work.. thanks Kris
private static Map getConstantFieldsAsMap(Class cls) {
Map propMap = null;
try {
Field[] allFields = cls.getDeclaredFields();
int numFields = allFields.length;
propMap = new HashMap(numFields);
for(int i = 0; i < numFields; i++) {
Field f = allFields[i];
int mods = f.getModifiers();
if(Modifier.isPublic(mods) && Modifier.isStatic(mods) &&
Modifier.isFinal(mods)) {
String name = f.getName();
Object value = f.get(null);
log.debug("Putting name = " + name + " and value=" + value
+ " into propMap");
propMap.put(name, value);
}
}
} catch(IllegalAccessException ie) {
log.error("Problem loading constantFieldsAsMap " + ie);
}
return Collections.unmodifiableMap(propMap);
}
//end class
Now in JSP you can just do:
<c:out value="${CONSTANTS.WHATEVER)"/>
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: using Constants from JSTL .....
Posted by Rick Reumann <st...@reumann.net>.
On Thu, 08 Jul 2004 09:43:11 -0400, Rick Reumann <st...@reumann.net>
wrote:
> <c:set var="emailNotifications"
> value="${servletContext[Constants.EMAIL_NOTIFICATIONS]}"/>
Duh, my bad, as David mentioned the above should be ${applicationScope..
}. Sorry about that.
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: using Constants from JSTL .....
Posted by Rick Reumann <st...@reumann.net>.
On Thu, 08 Jul 2004 13:49:11 +0200, Bryan Hunt <ad...@revoltingdigits.com>
wrote:
> <c:set var="emailNotifications"
> value="${scope[${Constants.EMAIL_NOTIFICATIONS}]}"></c:set>
Actually I haven't seen the 'scope' property like that, but have you tried
(assuming ApplicationScope)...
<c:set var="emailNotifications"
value="${servletContext[Constants.EMAIL_NOTIFICATIONS]}"/>
The above should work assuming you have a Constants class that is in
Application scope and Constants is either a Map (with a key
EMAIL_NOTFICATIONS) or a regular bean with a getEMAIL_NOTIFICATIONS method
in it.
--
Rick
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: using Constants from JSTL .....
Posted by Bryan Hunt <ad...@revoltingdigits.com>.
Hmmm, that gives me no error but no result either I put in the
following code to test it and just got blank
screen.
snip=
<jsp:useBean id="Constants" class="ie.jestate.web.Constants"/>
<c:set var="emailNotifications"
value="${scope[${Constants.EMAIL_NOTIFICATIONS}]}"></c:set>
<c:out value="${emailNotifications}"/>
<c:out value="${emailNotifications.priceRangeStart}"/>
<c:out value="${emailNotifications.priceRangeEnd}"/>
<c:forEach items="${emailNotifications.urbanAreas}" var="urbanArea">
<c:out value="${urbanArea.name}"/>
</c:forEach>
=snip
If I substitute the following line instead it works fine.
<c:set var="emailNotifications" value="${EMAIL_NOTIFICATIONS}"></c:set>
This line of code ...
<c:out value="${Constants.EMAIL_NOTIFICATIONS}"/>
Outputs
EMAIL_NOTIFICATIONS
on the screen.
I think this is starting to look like it just isn't going to work, I
don't think that jstl is too smart about dynamic
variables like this. I tried the other suggestion as well (
c:set var="const" value="${scope['Constants']}"/>
<c:set var="emailNotifications" value="${const['EMAIL_NOTIFICATIONS']}"/>
)
But it didn't work either, this is starting to look as though it will be
so convoluted that I might as well not be trying to use constants anyhow
as I will have to look up the file anyway I might as well just use
string literals.
Cause it isn't scriptlet I wont get auto-completion anyhow. I'm going
to try the suggestion from Rick Reumann and then I'm gonna throw my
computer out the window.
--b
Denis Avdic wrote:
>Have you tried
><c:set var="emailNotifications" value="${scope[Constants.EMAIL_NOTIFICATIONS]"/>
>?
>
>On Wed, 07 Jul 2004 20:12:02 +0200, Bryan Hunt
><ad...@revoltingdigits.com> wrote:
>
>
>>Just as an addition I can do this
>>
>><jsp:useBean id="Constants" class="ie.jestate.web.Constants"/>
>>
>><c:set var="emailNotifications" value="${EMAIL_NOTIFICATIONS}"></c:set>
>>
>><c:out value="${emailNotifications.priceRangeStart}"/>
>><c:out value="${emailNotifications.priceRangeEnd}"/>
>><c:forEach items="${emailNotifications.urbanAreas}" var="urbanArea">
>> <c:out value="${urbanArea.name}"/>
>></c:forEach>
>>
>>And it works fine, but really what I am trying to get here is the value
>>of using Constants in
>>both my Actions and my ( JSTL based ) jsp's.
>>
>>Perhaps this is just something that never occured to the writers of the
>>JSTL spec ?
>>
>>--b
>>
>>
>>
>>
>>Bryan Hunt wrote:
>>
>>
>>
>>>Ok, tearing my hair out right now and extremely confused.
>>>
>>>If you look at the Java Technology Forums you will see a rather nice
>>>little pattern that
>>>someone called evnafets has created, it allows you to use a single
>>>Constants class
>>>both in your Actions and in your JSP pages ...
>>>
>>>It uses reflection to add it's static final members to a map which can
>>>then be accessed by JSTL lik
>>>
>>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>>For additional commands, e-mail: user-help@struts.apache.org
>>
>>
>>
>>
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: using Constants from JSTL .....
Posted by Bryan Hunt <ad...@revoltingdigits.com>.
Just as an addition I can do this
<jsp:useBean id="Constants" class="ie.jestate.web.Constants"/>
<c:set var="emailNotifications" value="${EMAIL_NOTIFICATIONS}"></c:set>
<c:out value="${emailNotifications.priceRangeStart}"/>
<c:out value="${emailNotifications.priceRangeEnd}"/>
<c:forEach items="${emailNotifications.urbanAreas}" var="urbanArea">
<c:out value="${urbanArea.name}"/>
</c:forEach>
And it works fine, but really what I am trying to get here is the value
of using Constants in
both my Actions and my ( JSTL based ) jsp's.
Perhaps this is just something that never occured to the writers of the
JSTL spec ?
--b
Bryan Hunt wrote:
> Ok, tearing my hair out right now and extremely confused.
>
> If you look at the Java Technology Forums you will see a rather nice
> little pattern that
> someone called evnafets has created, it allows you to use a single
> Constants class
> both in your Actions and in your JSP pages ...
>
> It uses reflection to add it's static final members to a map which can
> then be accessed by JSTL lik
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org