【问题标题】:Custom converter in JSF 2 with argumentsJSF 2 中带参数的自定义转换器
【发布时间】:2012-07-21 17:23:11
【问题描述】:

我正在尝试实现一个自定义截断转换器,它在给定索引处截断字符串并添加一个延续符号。转换器工作正常,只有当我对参数进行硬编码时,因为它们没有被传递到后端。我做错了什么?

参数是转换器类的属性:

@FacesConverter(value = TruncateConverter.CONVERTER_ID)
public class TruncateConverter implements Converter, StateHolder
{
    public static final String CONVERTER_ID = "bla.blablabla.Truncate";

    private int truncateIndex;
    private String contSymbol;

这是我如何使用转换器(或尝试):

<h:outputText id="news-text-left" value="#{newsListBean.newsList_teaser.text}">
    <f:converter converterId="bla.blablabla.Truncate" truncateIndex="150" contSymbol="..." />
</h:outputText>

我用谷歌搜索了很多,但找不到一个带参数的 JSF2 转换器示例...谢谢大家的帮助,非常感谢!

【问题讨论】:

    标签: jsf jsf-2 converter


    【解决方案1】:

    您可以查看 JSF2.0 源代码。例如 DateTimeConverter... JSF 源代码在 svn 存储库中可用:https://svn.java.net/svn/mojarra~svn/trunk

    IMO 创建这样的转换器并不容易。它还需要创建转换器标签来注册转换器。

    将一些数据传递给转换器的其他方式是属性。所以你可以写

    <h:outputText ...>
      <f:converter converterId="bla.blablabla.Truncate" />
      <f:attribute name="truncateIndex" value="150"/>
    </h:outputText>
    

    比打电话给component.getAttributes().get("truncateIndex"); 在转换器代码中。

    【讨论】:

    • 你能注意到 f:attribute 不应该在转换器块内,它应该是 然后结束输出文本.该属性绑定到组件 id,而不是转换器本身。
    【解决方案2】:

    基于@Maks 解决方案:可以将转换器和属性组合在一个标签中:

    <facelet-taglib version="2.2"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_2.xsd">
        <namespace>http://mycompany.com/some-identifier</namespace>
        <tag>
            <tag-name>truncate</tag-name>
            <converter>
                <converter-id>bla.blablabla.Truncate</converter-id>
            </converter>
            <attribute>
                <name>truncateIndex</name>
            </attribute>
        </tag>
    </facelet-taglib>
    

    然后你可以像这样使用转换器:

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"
        xmlns:my="http://mycompany.com/some-identifier">
    
      <my:truncate truncateIndex="150" />
    
    </ui:composition>
    

    您也不需要从组件属性中获取参数。将自动填充具有相同名称的 bean-property:

    @FacesConverter("bla.blablabla.Truncate")
    public class Truncate implements Converter {
    
        private String truncateIndex;
    
        // getters + setters
    
        ...
    
    }
    

    【讨论】:

      【解决方案3】:

      http://jerryorr.blogspot.nl/2011/10/creating-jsf-12-custom-converter-with.html 是使用参数设置您的第一个自定义转换器的好指南

      【讨论】:

        【解决方案4】:

        我就是这样做的(在一个单独的 jar 文件中,并使用 maven 的默认目录):

        1) 创建转换器的类(在 src/main/java 内)

        2) 创建一个 .taglib.xml 类(在 src/main/resources/META-INF 内)

        3) 创建 faces-config.xml(在 src/main/resources/META-INF 内)

        例子:

        步骤 1)

        package com.ocabit.jsf.converter;
        
        
        
        import java.io.Serializable;
        import java.math.BigDecimal;
        import java.math.RoundingMode;
        import java.text.NumberFormat;
        
        import javax.faces.application.FacesMessage;
        import javax.faces.component.UIComponent;
        import javax.faces.context.FacesContext;
        import javax.faces.convert.Converter;
        import javax.faces.convert.ConverterException;
        import javax.faces.convert.FacesConverter;
        
        import org.springframework.stereotype.Service;
        
        import com.ocabit.utils.currency.CurrencyUtils;
        
        
        /**
         * Converter para valores BigDecimal.
         * 
         * @author Carlos Eduardo Pauluk
         * 
         */
        @FacesConverter("bigDecimalConverter")
        @Service("bigDecimalConverter")
        public class BigDecimalConverter implements Converter, Serializable {
        
            /**
             * 
             */
            private static final long serialVersionUID = 1L;
        
            public static final String CONVERTER_ID = "com.ocabit.jsf.converter.BigDecimalConverter";
        
            /**
             * Em caso de null, força a saída para 0.0;
             */
            private boolean nullToZero = false;
        
            /**
             * Em caso de zero, força a saída para null;.
             */
            private boolean zeroToNull = false;
        
            /**
             * Só retorna números positivos.
             */
            private boolean onlyAbs = false;
        
            /**
             * Só retorna números negativos.
             */
            private boolean onlyNeg = false;
        
            /**
             * Quantidade de casas decimais.
             */
            private int decimals = 2;
        
            @Override
            public Object getAsObject(final FacesContext context, final UIComponent component, final String value) {
                try {
                    BigDecimal bd = new BigDecimal(value);
                    bd = bd.setScale(getDecimals(), RoundingMode.HALF_DOWN);
        
                    if (bd.equals(BigDecimal.ZERO) && isZeroToNull()) {
                        return null;
                    }
        
                    if (isOnlyAbs()) {
                        bd = bd.abs();
                    }
                    if (isOnlyNeg()) {
                        bd = bd.abs();
                        bd = bd.negate();
                    }
        
                    return bd;
                } catch (final Exception e) {
                    BigDecimal bd = null;
                    if (isNullToZero()) {
                        bd = CurrencyUtils.getBigDecimalCurrency("0.0");
                        bd = bd.setScale(getDecimals(), RoundingMode.HALF_DOWN);
                    }
                    return bd;
                }
            }
        
            @Override
            public String getAsString(final FacesContext context, final UIComponent component, final Object value) {
                if (!(value instanceof BigDecimal)) {
                    throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao converter o valor decimal.", ""));
                }
        
                final NumberFormat nf = NumberFormat.getInstance();
                // sempre terá 2 casas decimais
                nf.setMinimumFractionDigits(2);
                nf.setMaximumFractionDigits(2);
                return nf.format(((BigDecimal) value).doubleValue());
            }
        
            public boolean isNullToZero() {
                return nullToZero;
            }
        
            public void setNullToZero(boolean nullToZero) {
                this.nullToZero = nullToZero;
            }
        
            public boolean isZeroToNull() {
                return zeroToNull;
            }
        
            public void setZeroToNull(boolean zeroToNull) {
                this.zeroToNull = zeroToNull;
            }
        
            public boolean isOnlyAbs() {
                return onlyAbs;
            }
        
            public void setOnlyAbs(boolean onlyAbs) {
                this.onlyAbs = onlyAbs;
            }
        
            public boolean isOnlyNeg() {
                return onlyNeg;
            }
        
            public void setOnlyNeg(boolean onlyNeg) {
                this.onlyNeg = onlyNeg;
            }
        
            public int getDecimals() {
                return decimals;
            }
        
            public void setDecimals(int decimals) {
                this.decimals = decimals;
            }
        
        }
        

        第 2 步)

        <!DOCTYPE facelet-taglib PUBLIC
            "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
            "facelet-taglib_1_0.dtd">
        <facelet-taglib version="2.2"
            xmlns="http://xmlns.jcp.org/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_2.xsd">
            <namespace>http://ocabit.com.br/facelets</namespace>
        
        
            <tag>
                <tag-name>convertBigDecimal</tag-name>      
                <converter>
                    <converter-id>com.ocabit.jsf.converter.BigDecimalConverter</converter-id>           
                </converter>    
            </tag>
        
        
        </facelet-taglib>
        

        步骤 3)

        <?xml version="1.0" encoding="UTF-8"?>
        <faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
            version="2.2">
        
            <converter>
                <description></description>
                <converter-id>com.ocabit.jsf.converter.BigDecimalConverter</converter-id>
                <converter-class>com.ocabit.jsf.converter.BigDecimalConverter</converter-class>
                <property>
                    <property-name>nullToZero</property-name>
                    <property-class>boolean</property-class>
                    <description>Ao invés de retornar 'null', retorna '0.0'</description>
                </property>
                <property>
                    <property-name>zeroToNull</property-name>
                    <property-class>boolean</property-class>
                    <description>Ao invés de retornar '0.0', retorna 'null'</description>
                </property>
                <property>
                    <property-name>onlyAbs</property-name>
                    <property-class>boolean</property-class>
                    <description>Somente retorna números positivos</description>
                </property>
                <property>
                    <property-name>onlyNeg</property-name>
                    <property-class>boolean</property-class>
                    <description>Somente retorna números negativos</description>
                </property>
                <property>
                    <property-name>decimals</property-name>
                    <property-class>int</property-class>
                    <description>Quantidade de casas decimais</description>
                </property>
            </converter>
        
        
        </faces-config>
        

        瞧。

        【讨论】:

          猜你喜欢
          • 2012-03-15
          • 1970-01-01
          • 2011-12-21
          • 1970-01-01
          • 2012-10-17
          • 2012-12-16
          • 1970-01-01
          • 2016-05-31
          • 2012-10-26
          相关资源
          最近更新 更多