Search code examples
javajspstruts2custom-tags

How to pass attributes(multiple attributes) to custom tags in struts 2?


I am currently working on struts upgrade(migrating from struts 1.x to 2.x)

My project has a custom tag handler class for formatting numbers in the application

TLD file

<taglib>
    <tlibversion>1.0</tlibversion>
    <jspversion>1.1</jspversion>
    <shortname>f</shortname>
    <uri>http://jakarta.apache.org/struts/tags-html</uri>   
   <tag>
        <name>formatNumber</name>
        <tagclass>com.taghandler.FormatNumberTag</tagclass>
        <bodycontent>empty</bodycontent>
        <attribute>
            <name>name</name>
            <required>true</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>property</name>
            <required>false</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>scope</name>
            <required>false</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>format</name>
            <required>false</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>       
    </tag>
   </taglib>

FormatNumberTag class

public class FormatNumberTag extends TagSupport
   {

    protected String name = null;

    protected String property = null;

    protected String scope = null;

    protected String format = null;

    //getters and setters of above member variables

    public int doStartTag() throws JspException
    {
        // Look up the requested bean (if necessary)
        Object bean = null;

        if (RequestUtils.lookup(pageContext, name, scope) == null)
        {
            return (SKIP_BODY); // Nothing to output
        }

        // Look up the requested property value
        Object value = RequestUtils.lookup(pageContext, name, property, scope);
        if (value == null)
        {
            return (SKIP_BODY); // Nothing to output
        }

        String output = null;

        if (format.equalsIgnoreCase(MyConstants.PRICE_FORMAT))
        {
            output = CustomConverter.priceFormat(value); //custom class which formats number
        }
        else if (format.equalsIgnoreCase(MyConstants.PERCENTAGE_FORMAT))
        {
            output = CustomConverter.positionFormat(value); //custom class which formats number
        }


        ResponseUtils.write(pageContext, output);

        // Continue processing this page
        return (SKIP_BODY);

    }
  }

JSP

<f:formatNumber name="AccountBean" property="floatingRate" format="percentage" />

Here, AccountBean is the bean, floatingRate is the property & percentage is the format.

1) In tag handler class above, (org.apache.struts.util.RequestUtils)RequestUtils.lookup & (org.apache.struts.util.ResponseUtils)ResponseUtils.write methods are used which are part of struts1 library.

  • What are the corresponding methods & classes to be used in struts 2?

2) In JSP, 3 values/attributes(accountBean, floatingRate, percentage) are passed in the custom tag.

  • How to pass attributes to custom tag in struts 2?

  • How to pass bean, property & format to custom tag in struts 2? Please provide an example


Solution

  • In a Struts2 application, you can easily make use of the internationalization support in conjunction with the s:text tag in order to render formatted text.

    By adding the following messages to the internationalization property files associated with the action or by defining a global message file via struts.custom.i18n.resources:

    format.price={0,number,#,###,##0.00}
    format.price.with.currency={0,number,#,###,##0.00} {1}
    format.percentage={0,number,#,##0.00}%
    

    Then in order to render them, your JSP code might resemble the following:

    <!-- Render listItemPrice using the format.price layout -->
    <s:text name="format.price"><s:param value="accountBean.listItemPrice"/>  
    
    <!-- Render listItemPrice with currency code -->
    <s:text name="format.price">
      <s:param value="accountBean.listItemPrice"/>
      <s:param value="accountBean.currencyCode"/>
    </s:text>
    
    <!-- Render percentage -->
    <s:text name="format.percentage">
      <s:param value="accountBean.floatingRate"/>
    </s:text>
    

    UPDATE

    If you need custom formatting, you can also leverage the s:component tag.

    <s:component template="/components/numeric-format.ftl">
      <s:param name="type" value="%{'price'}" />
      <s:param name="value" value="%{accountBean.floatingRate}"/>
    </s:component>
    

    You can then define the /components/numeric-format.ftl freemarker template and add any specific logic you need

    <span class="<#if parameters.value < 0>negative</#if><#else>positive</#else>">
      <@s.if test="${parameters.type?default('')} eq 'price'">
        <@s.text name="format.price">
          <@s.param value="${parameters.value}"/>
        </@s.text/>
      </@s.if>
      <#-- add other if blocks for various types and formats -->
    </span>