struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christoph Nenning <Christoph.Nenn...@lex-com.net>
Subject Antwort: OGNL Indexed and Object Indexed Properties
Date Tue, 20 May 2014 08:02:07 GMT
> Question:
> According to OGNL (
> http://commons.apache.org/proper/commons-ognl/language-guide.html) under
> heading JavaBeans Indexed Properties and OGNL Object Indexed Properties,
> getFieldWithIndex(int index) should be called, but it isn't, same goes 
with
>  getFieldWithKey(String key), why ?
> I looked at the latest OGNL source code (not the one I'm using since I
> couldn't find the source code for version 3.0.6) hoping if I could spot 
a
> method where it tries different get/set methods.
> Tried setting breakpoints at OGNLRuntime, ObjectPropertyAccessor but
> coulnd't see anything obvious.
> 
> At the moment I have a few workarounds
> 1. Use the ones that are working, i.e. getFieldList() and getFieldMap(),
> implementing my own List and Map


Another way would be OGNL method call syntax:

<s:property value="getFieldWithIndex(1)"/>





> 2. Use java.util.List getList() and setList(java.util.List list), struts
> will create a new List and populate accordingly in the order in which 
they
> were submitted in the form
> The issue with this is, if I have a pair or triplet of things that go 
hand
> in hand, then it gets complex.
> e.g.
> name and address where address is optional
> in the form the user put name1, address1, name2 (with no address), and
> name3, address3
> struts calls setName() with List containing name1, name2, name3
> it also calls setAddress() with List containing address1, address3
> There is no way the code can then figure out that that address3 is 
actually
> associated with name3
> In the past I was able to get around this by supplying another data
> structure that tells the code which address belongs to which name but it
> involves JavaScript, and it gets messy quite quickly.



struts/OGNL can store mulitple values in a map. You could use name as key 
and address as value:

address: <s:textfield name="map['name']" />

That works well when you know names during "get phase" (when users cannot 
change names on that particular form).
If users can also enter names here, you need javascript.

Another use case of that map syntax is when the number of input fileds is 
dynamic.




> 3. "Bypass" struts, in the "get" phase (showing the form) just use 
straight
> html combined with struts tags, during the "set" phase (submitting the
> form), will just get the parameters using HttpServletRequest
> e.g. during show form
> <input type="text" name="whateverName" value="<s:property
> value="whateverValue"/>"/>
> instead of
> <s:textfield ... />


This is always possible, of course. It means you have to generate 
parameter names during GET and parse them on POST.

Usually I try to avoid this in my applications but there are (rare) cases 
I need to do that.
If you do so, you have to think of how you do validation. You can still 
use struts validation when you generate the same parameter names again (in 
validate() method) and use <s:fieldError> tags with the same generated 
names.





Regards,
Christoph






> 
> OGNL Indexed and Object Indexed Properties
> 
> Hi,
> 
> I'm wondering why this code is not working. I'm using struts 2.3.16.1 
and
> ognl 3.0.6.
> 
> In my action class I have this
> 
> public String[] getFieldArray() {
> System.out.println(">> getFieldArray()");
> return null;
> }
> 
> public void setFieldArray(String[] array) {
> }
> 
> public MyList<String> getFieldList() {
> System.out.println(">> getFieldList()");
> return new MyList<String>();
> }
> 
> public void setFieldList(MyList<String> list) {
> }
> 
> public MyMap<String, String> getFieldMap() {
> System.out.println(">> getFieldMap()");
> return new MyMap<String, String>();
> }
> 
> public void setFieldMap(MyMap<String, String> map) {
> 
> }
> 
> public String getFieldWithIndex(int index) {
> System.out.println(">> getFieldWithIndex(" + index + ")");
> return null;
> }
> 
> public void setFieldWithIndex(int index, String value) {
> System.out.println(">> setFieldWithIndex(" + index + "," + value + ")");
> }
> 
> public String getFieldWithKey(String key) {
> System.out.println(">> getFieldWithKey(" + key + ")");
> return null;
> }
> 
> public void setFieldWithKey(String key, String value) {
> System.out.println(">> setFieldWithKey(" + key + "," + value + ")");
> }
> 
> Note that MyList and MyMap are as follows
> 
> class MyMap<K, V> implements Map<K, V> { ... }
> class MyList<V> implements List<V> { ... }
> 
> I have the get() methods overridden on the those classes
> 
> On my jsp I have this
> 
> <s:property value="fieldArray[1]"/>
> <s:property value="fieldList[1]"/>
> <s:property value="fieldMap['1']"/>
> <s:property value="fieldWithIndex[1]"/>
> <s:property value="fieldWithKey['1']"/>
> 
> Result is
> 
> >> getFieldArray()
> >> getFieldList()
> MyList.get(1)
> >> getFieldMap()
> MyMap.get(1)
> MyMap.get(1)
> 
> Question:
> According to OGNL (
> http://commons.apache.org/proper/commons-ognl/language-guide.html) under
> heading JavaBeans Indexed Properties and OGNL Object Indexed Properties,
> getFieldWithIndex(int index) should be called, but it isn't, same goes 
with
>  getFieldWithKey(String key), why ?
> I looked at the latest OGNL source code (not the one I'm using since I
> couldn't find the source code for version 3.0.6) hoping if I could spot 
a
> method where it tries different get/set methods.
> Tried setting breakpoints at OGNLRuntime, ObjectPropertyAccessor but
> coulnd't see anything obvious.
> 
> At the moment I have a few workarounds
> 1. Use the ones that are working, i.e. getFieldList() and getFieldMap(),
> implementing my own List and Map
> 
> 2. Use java.util.List getList() and setList(java.util.List list), struts
> will create a new List and populate accordingly in the order in which 
they
> were submitted in the form
> The issue with this is, if I have a pair or triplet of things that go 
hand
> in hand, then it gets complex.
> e.g.
> name and address where address is optional
> in the form the user put name1, address1, name2 (with no address), and
> name3, address3
> struts calls setName() with List containing name1, name2, name3
> it also calls setAddress() with List containing address1, address3
> There is no way the code can then figure out that that address3 is 
actually
> associated with name3
> In the past I was able to get around this by supplying another data
> structure that tells the code which address belongs to which name but it
> involves JavaScript, and it gets messy quite quickly.
> 
> 3. "Bypass" struts, in the "get" phase (showing the form) just use 
straight
> html combined with struts tags, during the "set" phase (submitting the
> form), will just get the parameters using HttpServletRequest
> e.g. during show form
> <input type="text" name="whateverName" value="<s:property
> value="whateverValue"/>"/>
> instead of
> <s:textfield ... />

This Email was scanned by Sophos Anti Virus

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message