I've tried to get attributeNames of a ill-maintained context, then use those names with reflection.
Here's some pseudo code for a rough idea. E.g. I have an ArrayList and a Hash开发者_JAVA技巧Map in the context.
enum = getServletContext().getAttributeNames();
for (; enum.hasMoreElements(); ) {
String name = (String)enum.nextElement();
// Get the value of the attribute
Object value = getServletContext().getAttribute(name);
if (value instanceof HashMap){
HashMap hmap = (HashMap) value;
//iterate and print key value pair here
}else if(value instanceof ArrayList){
//do arraylist iterate here and print
}
}
Here's code that will do what you want:
Enumeration<?> e = getServletContext().getAttributeNames();
while (e.hasMoreElements())
{
String name = (String) e.nextElement();
// Get the value of the attribute
Object value = getServletContext().getAttribute(name);
if (value instanceof Map) {
for (Map.Entry<?, ?> entry : ((Map<?, ?>)value).entrySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
} else if (value instanceof List) {
for (Object element : (List)value) {
System.out.println(element);
}
}
}
Notes:
- Always favour referring to the abstract interface over concrete implementations. In this case, check for
List
andMap
(interfaces), rather thanArrayList
andHashMap
(specific implementations); consider what will happen if the context hands you aLinkedList
rather than anArrayList
, or aMap
that's not aHashMap
- your code would (unnecessarily) explode - Use
while (condition)
rather thanfor (;condition;)
- it's just ugly - If you know the types of your Collections, specify them. For example, web contexts usually give you a
Map<String, Object>
:
so the code could become
for (Map.Entry<String, Object> entry : ((Map<String, Object>)value).entrySet()) {
String entryKey = entry.getKey();
Object entryValue = entry.getValue();
}
精彩评论