JSF and EL, I don't understand this code (an array?) - jsf-2

I was reading some code and I found the next EL expression inside a JSF file:
${text['somefield']}
How is it work?.
Since I don't have access to the whole code, I can check what it is. Is it "text" a managed bean?.
Because I could understand the next code:
${someBean.text['somefield']}
(accessing a field array inside a bean but it's not the case.

text can be a managed bean, a CDI dependency (these are the 2 most likely)
text['somefield'] is reading somefield field of text object. text is likely to be a map, but it could be a normal bean too. It's equivalent to text.somefield
In the documentation, you can also find similar exampes:
${customer.address["street"]}
Which is similar to:
${customer.address.street}

Related

JSF el not resolving

I have the following line in a JSF page:
<h:commandLink action="#{myBean.test}" value="Wizard Step"></h:commandLink>
I expect that when the page is loaded, the Bean corresponding to myBean will be instantiated (and I'll be able to see this in the eclipse debugger).
The rest of the JSF is working correctly, but this bean is not resolving (without any error).
How do I get the errors from the el failing to resolve the bean?
If there are EL errors, you will surely get an exception of javax.el package:
ELException: Represents any of the exception conditions that can arise during expression evaluation.
MethodNotFoundException: Thrown when a method could not be found while evaluating a MethodExpression.
PropertyNotFoundException: Thrown when a property could not be found while evaluating a ValueExpression or MethodExpression.
PropertyNotWritableException: Thrown when a property could not be written to while setting the value on a ValueExpression.
In your case, the managed bean is not constructed on initial request. This can only mean that the managed bean is not referenced elsewhere in the view. The EL in action attribute is only evaluated when the form is submitted. So the bean will only be constructed when the action is invoked. As a test, just put #{myBean} somewhere in the view. You'll see that it get constructed on initial request.
Your real problem is that command button action is simply not invoked, so the EL in its action attribute is simply not evaluated at all. The problem cannot be debugged nor nailed down in the EL side. There are a lot of possible causes for the button action not being invoked. You can find them all here: commandButton/commandLink/ajax action/listener method not invoked or input value not updated. The most common cause among starters is that the button is inside an repeating component like <h:dataTable> whose value is not properly preserved and returns a completely different value during the form submit request, or that the component or one of its components has a rendered attribute which is not properly preserved and defaults to false.

JSF component binding without bean property

How does exactly the following code work:
#{aaa.id}
<h:inputText id="txt1" binding="#{aaa}"/>
I mean, usually the component binding works, by specifying a property (of type UIComponent) in a bean. Here, there's no bean nor property but nevertheless the name "aaa" gets bound correctly (displaying the component id - "txt1"). How does it work/where is it specified?
Thanks
UPDATE: The JSF2.0 Spec [pdf] (Chapter 3.1.5) says:
"A component binding is a special value expression that can be used to facilitate “wiring up” a component instance to a
corresponding property of a JavaBean... The specified ValueExpression must point to a read-write JavaBeans property of type UIComponent (or
appropriate subclass)."
It's been put in the default EL scope during building of the view tree (that's when all binding attributes -- and attributes of tag handlers like JSTL <c:xxx> and JSF <f:xxx> -- are being evaluated). It's being shown by normal EL means during rendering of the view tree. Rendering of the view tree happens after building of the view tree, so it works that way. It's not that this code runs "line by line" as you seemed to expect from the source.
I can't point you out a single reference where it's been specified as there is none. You'd have to read both the EL spec and JSF spec separately and do a 1+1=2.
By the way, to avoid confusion among new developers and to avoid clashes with existing variables in the EL scopes, you can use a java.util.HashMap in the request scope which is been declared as follows in faces-config.xml:
<managed-bean>
<description>Holder of all component bindings.</description>
<managed-bean-name>components</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
and is been used as follows
#{components.aaa.id}
<h:inputText id="txt1" binding="#{components.aaa}"/>
which is more self-documenting.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?

OGNL exceptions setting Struts2 checkbox value

After adding a s:checkbox to my form, I get OGNL errors in the ParamsInterceptor:
WARN [OgnlValueStack] Error setting expression '__checkbox_filter.findRejected' with value '[Ljava.lang.String;#dc926f'
ognl.OgnlException: target is null for setProperty(null, "findRejected", [Ljava.lang.String;#dc926f)
I am aware that the extra hidden field with underscores in its name (__checkbox_filter.findRejected) was correctly added by Struts2.
I don't understand, however, why the ParametersInterceptor is trying to set this property, that was added by Struts2, on my Action (which obviously doesn't contain a '__checkbox_filter' property).
It is normal to see this OGNL error coming from with Struts2 checkboxes? How can I avoid it?
I've just stumble across the very same problem.
You need to place the Checkbox Interceptor BEFORE the Parameters Interceptor in your interceptor stack.
This is the case by default, so I guess that you're using a custom stack...
Most of the time the mistake in such cases is that we forget to write getters and setters for the attributes. So check whether the getters and setters are at their place.

Getting bean properties names in Grails

I'm trying to write a tag, which will render my bean properties and corresponding values. I want the default behaviour be to render all properties from the bean. So I need somehow get all property names from passed bean.
I figured that I could use properties map, but despite bean properties, there are also other things and I'd have to manage it by hand which may be error prone.
I also thought of using DefaultGrailsDomainClass which is handy for domain classes, but is useless for command objects.
Have you ever done something similar and came up with something useful?
Like said here, there are also persistentProperties. But I believe you need GrailsDomainClass.properties - don't confuse with Groovy properties, the former are for domain class.
For rendering, GrailsDomainClassProperty.naturalName will also be useful.
I've done similar thing by using properties, no problem. My code was:
value.properties.entrySet().each { Map.Entry it ->
println "$it.key = $it.value"
}

Struts2 form to action fields mapping automatically

I would like to know if it is possible, in Struts2, to map an HTML form's fields to those of an action, automatically, without getters and setters.
It is clear that by getters and setters or the ParameterAware interface and the Map, fields can be set in the action, but I just wanted to know if otherwise there was a way.
First, instead of thinking in terms of "with fields with getters and setters" you are advised to think in terms of "bean properties" here. Struts2 (and most java frameworks) think in that way, they usually don't care (and rightly so) whether those "properties" are real fields or not.
The short answer to your question is: no.
But be aware that Struts2 is very flexible - when I say "no" I mean "using the default interceptors". You could always write your own interceptor instead of the default to do that - bad idea IMO.
The interceptor that does that mapping is (basically) the parameters interceptor. From its documentation:
This interceptor gets all parameters
from ActionContext#getParameters() and
sets them on the value stack by
calling ValueStack#setValue(String, Object)
typically resulting in the values
submitted in a form request being
applied to an action in the value
stack.
And looking into ValueStack.setValue(String,Object) we read:
Attempts to set a property on a
bean in the stack with the given
expression using the default search
order.
So there you have.
ModelDriven was the correct choice :)

Resources