In JSF 2 I have declared function inspect
which takes one argument of type java.lang.reflect.Method
and based on this argument it performs some annotation inspection and returns true
or false
. The catch is I want to call this function inspect
from JSF EL to be able to modify UI according the return value but I am not able to get a reference of target method to pass it as an argument of the function, so I would like to ask how to do it?
Example
package some.pkg;
@ManagedBean( name = "someClass" )
public class SomeClass {
@MyAnnotation
public void someMethod( String arg1, Integer arg2 ) { /* ... */ }
}
JSF function declaration
<function>
<function-name>inspect</function-name>
<function-class>some.pkg.Inspector</function-class>
<function-signature>boolean inspect(java.lang.reflect.Method)</function-signature>
</function>
Desired invocation from JSF, but it doesn't work
<h:outputText
value="someMethod is annotated by @MyAnnotation"
rendered="#{inspect(someClass.someMethod)}"
/>
Acceptable would be also this, but it is less comfortable variant
<h:outputText
value="someMethod is annotated by @MyAnnotation"
rendered="#{inspect(some.pkg.SomeClass.someMethod)}"
/>
If you are using EL > 2.2 you don't need your custom EL-function. You can call the method from your ManagedBean directly with parameters:
#{someClass.someMethod('foo', 42)}
Otherwise you must declare a namespace and use it before your function:
#{namespace:inspect(someClass.someMethod)}
You can find a good explanation here .
But I'm not sure if this will work in your case. Even if it's possible to pass java.lang.reflect.Method
as Parameter (never tried) how should the Method get their parameters? Nobody is passing them.
Why don't you try it just in server side? You know before rendering the page if the method is annotated in the current bean or not, so:
@ManagedBean( name = "someClass" )
public class SomeClass {
boolean annotated = false;
public boolean isAnnotated(){
return annotated;
}
@PostConstruct
public void postConstruct(){
if (inspect(this.getClass().getMethod("someMethod")){
annotated=true;
}
}
}
And in your xhtml page:
<h:outputText
value="someMethod is annotated by @MyAnnotation"
rendered="#{someClass.annotated}"
/>
You can even adapt it to use a parameter and calculate it on-the-fly:
//Notice in this case we're using a METHOD, not a GETTER
public boolean annotated(String methodName){
return inspect(this.getClass().getMethod(methodName);
}
Calling it like that:
<h:outputText
value="someMethod is annotated by @MyAnnotation"
rendered="#{someClass.annotated('methodName')}"
/>
Or you can use an @ApplicationScoped
managed bean to have access to it from every single view:
@ManagedBean
@ApplicationScoped
public class InspectorBean{
public boolean inspectMethod(String className, String methodName){
return inspect(Class.forName(className).getMethod(methodName));
}
}
Then you can access like that from all your views:
<h:outputText
value="someMethod is annotated by @MyAnnotation"
rendered="#{inspectorBean.inspectMethod('completeClassName','methodName')}"
/>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.