I have some classes which extends a superclass, and in the JSP I want to show some attributes of these classes. I only want to make one JSP, but I don\'t know in advance if the
Make use of JSTL c:catch.
<c:catch var="exception">${myObject.myAttribute}</c:catch>
<c:if test="${not empty exception}">Attribute not available.</c:if>
You can readily create a custom function to check for the property, as per vivin's blog post.
In short, if you already have your own taglib its just a matter of creating a static 'hasProperty' method...
import java.beans.PropertyDescriptor;
import org.apache.commons.beanutils.PropertyUtils;
...
public static boolean hasProperty(Object o, String propertyName) {
if (o == null || propertyName == null) {
return false;
}
try
{
return PropertyUtils.getPropertyDescriptor(o, propertyName) != null;
}
catch (Exception e)
{
return false;
}
}
...and adding five lines to your TLD...
<function>
<name>hasProperty</name>
<function-class>my.package.MyUtilClass</function-class>
<function-signature>boolean hasProperty(java.lang.Object,
java.lang.String)
</function-signature>
</function>
... and calling it in your JSP
<c:if test="${myTld:hasProperty(myObject, 'myAttribute')}">
<c:set var="foo" value="${myObject.myAttribute}" />
</c:if>
Just a more detailed (typical?) usage of BalusC great answer
<%--
[1] sets a default value for variable "currentAttribute"
[2] check if myObject is not null
[3] sets variable "currentAttribute" to the value of what it contains
[4] catches "property not found exception" if any
- if exception thrown, it does not output anything
- if not exception thrown, it outputs the value of myObject.myAttribute
--%>
<c:set var="currentAttribute" value="" /> <%-- [1] --%>
<c:if test="${not empty myObject}"> <%-- [2] --%>
<c:set var="currentAttribute"> <%-- [3] --%>
<c:catch var="exception">${myObject.myAttribute}</c:catch> <%-- [4] --%>
</c:set>
</c:if>
<%-- use the "currentAttribute" variable without worry in the rest of the code --%>
currentAttribute is now equal to: ${currentAttribute}
As pointed out by Shervin in the comments of BalusC's answer, this is probably NOT the cleanest solution but as replied by BalusC "that's so far the only way to achieve the odd requirement".
Resources
Do you mean something like this:
<c:if test="${not null myObject.myAttribute}">
<!-- Now I can access safely to "myAttribute" -->
</C:if>
or other variant
<c:if test="${myObject.myAttribute != null}">
<!-- Now I can access safely to "myAttribute" -->
</C:if>
If it is a list you can do
<c:if test="#{not empty myObject.myAttribute}">
The accepted answer may have some side effects when I just want to test if the object has a field, but do not want to output the value of the field. In the mentioned case, I use the snippet below:
<c:catch var="exception">
<c:if test="${object.class.getDeclaredField(field) ne null}">
</c:if>
</c:catch>
hope this helps.