Uploaded image for project: 'Struts 2'
  1. Struts 2
  2. WW-4641

Pre-evaluation of "name" attribute stopped working

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.3.20
    • Fix Version/s: 2.3.30
    • Component/s: Expression Language
    • Labels:
    • Environment:

      apache tomcat 6.0.27

      Description

      Hi Team,

      http://struts.apache.org/docs/s2-029.html

      please suggest the replacement code for %

      {..}

      for the latest version of the struts 2.3.28

      Thanks
      Sambasiva Rao

        Issue Links

          Activity

          Hide
          lukaszlenart Lukasz Lenart added a comment -

          pre-evaluation of name was restored.

          Show
          lukaszlenart Lukasz Lenart added a comment - pre-evaluation of name was restored.
          Hide
          ghuber Greg Huber added a comment -

          OK, great, guess we have gone full circle now

          ...As there are web.xml, struts.xml and dtd changes for v2.5, testing prior releases is problematic for me, so best to switch to the latest versions if upgrading. Also latest versions will get more much testing by me!

          Show
          ghuber Greg Huber added a comment - OK, great, guess we have gone full circle now ...As there are web.xml, struts.xml and dtd changes for v2.5, testing prior releases is problematic for me, so best to switch to the latest versions if upgrading. Also latest versions will get more much testing by me!
          Hide
          lukaszlenart Lukasz Lenart added a comment -

          Yes, this affects only 2.3.29

          Show
          lukaszlenart Lukasz Lenart added a comment - Yes, this affects only 2.3.29
          Hide
          ghuber Greg Huber added a comment - - edited

          ....hm, this would have also broken my system but has not:

          <s:hidden id="1" name="eventList(%{#list.sequence}).id.eventCategory" value="%{#list.id.eventCategory}" />
          <s:hidden id="2" name="eventList(%{#list.sequence}).id.eventCategory"/>
          

          but renders correctly:

          <input id="1" type="hidden" value="myvalue" name="eventList(1).id.eventCategory">
          <input id="2" type="hidden" value="myvalue" name="eventList(1).id.eventCategory">
          

          I am running v2.5.1 maybe the mods do not effect this version?

          Show
          ghuber Greg Huber added a comment - - edited ....hm, this would have also broken my system but has not: <s:hidden id= "1" name= "eventList(%{#list.sequence}).id.eventCategory" value= "%{#list.id.eventCategory}" /> <s:hidden id= "2" name= "eventList(%{#list.sequence}).id.eventCategory" /> but renders correctly: <input id= "1" type= "hidden" value= "myvalue" name= "eventList(1).id.eventCategory" > <input id= "2" type= "hidden" value= "myvalue" name= "eventList(1).id.eventCategory" > I am running v2.5.1 maybe the mods do not effect this version?
          Hide
          dario.liberman.accenture.com Dario Liberman added a comment -

          Hi Greg,

          No need to introduce an iterator to see the issue. Also, please disregard the id attribute. The key here is to have an expression in the name attribute without providing a value attribute. The value should be automatically extracted by evaluating the name expression. This effectively means that the name attribute is evaluated twice:

          1. In order to produce the final name to be rendered in the input -> eval(name)
          2. In order to retrieve the value to be rendered in the input -> eval(eval(name))

          Your example could be re-written as follows:

          <s:hidden name="eventList[%{#bean.sequence}].sequence" />
          

          Notice above that I am not providing a value explicitly.

          Here the new test that would be breaking without reverting the offending changes in UIBean:
          https://git1-us-west.apache.org/repos/asf?p=struts.git;a=blobdiff;f=core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java;h=806420480e1eee141ab1558ea991e8f415a2ccc6;hp=d8143084cfd8d7cad4e26765be0b789483edd7b8;hb=f096dd61;hpb=cfcefcf5898313043ef903ce0873b15fb7cf1df4

          Thanks,
          Dario.

          Show
          dario.liberman.accenture.com Dario Liberman added a comment - Hi Greg, No need to introduce an iterator to see the issue. Also, please disregard the id attribute. The key here is to have an expression in the name attribute without providing a value attribute. The value should be automatically extracted by evaluating the name expression. This effectively means that the name attribute is evaluated twice: In order to produce the final name to be rendered in the input -> eval(name) In order to retrieve the value to be rendered in the input -> eval(eval(name)) Your example could be re-written as follows: <s:hidden name= "eventList[%{#bean.sequence}].sequence" /> Notice above that I am not providing a value explicitly. Here the new test that would be breaking without reverting the offending changes in UIBean: https://git1-us-west.apache.org/repos/asf?p=struts.git;a=blobdiff;f=core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java;h=806420480e1eee141ab1558ea991e8f415a2ccc6;hp=d8143084cfd8d7cad4e26765be0b789483edd7b8;hb=f096dd61;hpb=cfcefcf5898313043ef903ce0873b15fb7cf1df4 Thanks, Dario.
          Hide
          ghuber Greg Huber added a comment - - edited

          OK, do not understand the question, so giving up now

          <s:iterator var="bean" value="eventList">
          <s:hidden name="eventList[%{#bean.sequence}].sequence" value="%{#bean.sequence}" />
          

          yields

          <input type="hidden" name="eventList[1].sequence" value="1">

          Show
          ghuber Greg Huber added a comment - - edited OK, do not understand the question, so giving up now <s:iterator var= "bean" value= "eventList" > <s:hidden name= "eventList[%{#bean.sequence}].sequence" value= "%{#bean.sequence}" /> yields <input type="hidden" name="eventList [1] .sequence" value="1">
          Hide
          ghuber Greg Huber added a comment - - edited

          If %{bean.id} is not referring to id="bean" of the iterator, rather the page bean, then I am incorrect as have not understood the issue.

          <s:iterator value="beanList" id="bean">
          <s:textfield name="beanList(%{bean.id}).name" />
          

          this works for me:

          <s:iterator var="bean" value="eventList">
          <s:hidden name="eventList(%{#bean.sequence}).sequence" value="%/{#bean.sequence}" />
          

          which constructs name="eventList(1).sequence"

          Show
          ghuber Greg Huber added a comment - - edited If %{bean.id} is not referring to id="bean" of the iterator, rather the page bean, then I am incorrect as have not understood the issue. <s:iterator value= "beanList" id= "bean" > <s:textfield name= "beanList(%{bean.id}).name" /> this works for me: <s:iterator var= "bean" value= "eventList" > <s:hidden name= "eventList(%{#bean.sequence}).sequence" value= "%/{#bean.sequence}" /> which constructs name="eventList(1).sequence"
          Hide
          ghuber Greg Huber added a comment - - edited

          https://struts.apache.org/docs/iterator.html

          The id attribute is deprecated in Struts 2.1.x, and has been replaced by the var attribute.

          <s:iterator value="beanList" id="bean">
                <s:textfield name="beanList(%{bean.id}).name" />
          </s:iterator>
          

          use:

          <s:iterator value="beanList" var="bean">
                <s:textfield name="beanList(%{bean.id}).name" />
          </s:iterator>
          
          Show
          ghuber Greg Huber added a comment - - edited https://struts.apache.org/docs/iterator.html The id attribute is deprecated in Struts 2.1.x, and has been replaced by the var attribute. <s:iterator value= "beanList" id= "bean" > <s:textfield name= "beanList(%{bean.id}).name" /> </s:iterator> use: <s:iterator value= "beanList" var= "bean" > <s:textfield name= "beanList(%{bean.id}).name" /> </s:iterator>
          Hide
          lukaszlenart Lukasz Lenart added a comment -

          This is a regression :\

          Show
          lukaszlenart Lukasz Lenart added a comment - This is a regression :\
          Hide
          martin.tsv Martin Tsvetkov added a comment - - edited

          Hi,

          We are having issues after upgrading to Struts 2.3.29, whereby expressions inside name attributes of tags with %{…} in them would no longer be evaluated to retrieve the value.

          For example:

          <s:textfield id="qty%{#entry.entryId}" name="basket.entryList[%{#entry.entryId}].quantity" />
          

          This boils down to a change in org.apache.struts2.components.UIBean#evaluateParams()
          https://git-wip-us.apache.org/repos/asf?p=struts.git;a=commit;h=88b885339a6cb7e31393cbb723a57ddf8f8b4494

          BEFORE

          if (this.name != null) {
                      name = findString(this.name);
                      addParameter("name", name);
                 }
          

          AFTER

          if (this.name != null) {
                      addParameter("name", findString(this.name));
                 }
          

          Affected value logic further down

          if (value != null) {
                                  addParameter("nameValue", findValue(value, valueClazz));
                              } else if (name != null) {
                                  String expr = completeExpressionIfAltSyntax(name);
          
                                  addParameter("nameValue", findValue(expr, valueClazz));
                              }
          

          Is this intentionally changed so that the final name would not be evaluated to retrieve the value?
          Is it somehow related to https://cwiki.apache.org/confluence/display/WW/S2-036 ?

          Thanks,
          Martin

          Show
          martin.tsv Martin Tsvetkov added a comment - - edited Hi, We are having issues after upgrading to Struts 2.3.29, whereby expressions inside name attributes of tags with %{… } in them would no longer be evaluated to retrieve the value. For example: <s:textfield id= "qty%{#entry.entryId}" name= "basket.entryList[%{#entry.entryId}].quantity" /> This boils down to a change in org.apache.struts2.components.UIBean#evaluateParams() https://git-wip-us.apache.org/repos/asf?p=struts.git;a=commit;h=88b885339a6cb7e31393cbb723a57ddf8f8b4494 BEFORE if ( this .name != null ) { name = findString( this .name); addParameter( "name" , name); } AFTER if ( this .name != null ) { addParameter( "name" , findString( this .name)); } Affected value logic further down if (value != null ) { addParameter( "nameValue" , findValue(value, valueClazz)); } else if (name != null ) { String expr = completeExpressionIfAltSyntax(name); addParameter( "nameValue" , findValue(expr, valueClazz)); } Is this intentionally changed so that the final name would not be evaluated to retrieve the value? Is it somehow related to https://cwiki.apache.org/confluence/display/WW/S2-036 ? Thanks, Martin
          Hide
          lukaszlenart Lukasz Lenart added a comment -

          It's suggestion to not force evaluate incoming params using %{...} - you can still use this approach for internal values

          Show
          lukaszlenart Lukasz Lenart added a comment - It's suggestion to not force evaluate incoming params using %{...} - you can still use this approach for internal values

            People

            • Assignee:
              lukaszlenart Lukasz Lenart
              Reporter:
              dsambasivarao Samba
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - 168h
                168h
                Remaining:
                Remaining Estimate - 168h
                168h
                Logged:
                Time Spent - Not Specified
                Not Specified

                  Development