0

多くの XHTML ページがあり、各ページには<h:inputText><h:inputSecret>などの入力コンポーネントがあります。

フォームを送信する前に、これらすべての値をトリミングする一般的な方法を見つけようとしています。

TrimInputTextRendererクラスを実装しましたが、

XHTML ページ:

<h:inputText value="#{userBean.emailAddress}" trim="true">
       <f:validator validatorId="emailAddressValidator"/>
</h:inputText>

TrimInputTextRenderer.java:

package com.vyan.web.component;

import java.io.IOException;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.render.FacesRenderer;

import com.sun.faces.renderkit.html_basic.TextRenderer;

@FacesRenderer(componentFamily="javax.faces.Input", rendererType="javax.faces.Text")
public class TrimInputTextRenderer extends TextRenderer {

    private void encodeBeginForChildren(FacesContext context, UIComponent component) {
            if (component instanceof UIInput) {
                component = (UIInput)component;
                String componentValue = ((UIOutput)component).getValue().toString();
                componentValue = (componentValue!=null)?componentValue.trim():componentValue;
                ((UIInput)component).setValue(componentValue);
            }

            // Encoding recursively all childrens.
            if (component.isRendered() && component.getChildCount() > 0)
                encodeBeginForChildrens(context, component.getChildren());

    }

    private void encodeBeginForChildrens(FacesContext context, List<UIComponent> children) {
        for (UIComponent comp : children) {
            if (comp instanceof UIInput) {
                comp = (UIInput) comp;
                ((UIInput) comp).setValue(((UIInput) comp).getValue()
                        .toString().trim());
            }

                    // Encoding recursively all childrens.
            if (comp.isRendered() && comp.getChildCount() > 0)
                encodeBeginForChildrens(context, comp.getChildren());
        }

    }

    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
        String trimValue = (String) component.getAttributes().get("trim");
        if (trimValue!= null && Boolean.valueOf(trimValue)) {
            //super.write(string);
            encodeBeginForChildren(context, component);
        } 
        super.encodeBegin(context, component);
    }

}

faces-config.xml:

<render-kit>
        <renderer>
            <component-family>javax.faces.Input</component-family>
            <renderer-type>javax.faces.Text</renderer-type>
            <renderer-class>com.vyan.web.component.TrimInputTextRenderer</renderer-class>
        </renderer>
    </render-kit>

問題は、すべてが正常に機能し、カスタム レンダラーが値をトリミングすることです。ただし、バリデータとマネージド Bean のコンポーネント値が必要です。TrimInputTextRenderer#encodeBegin()それらはメソッドメソッド呼び出しの前に実行されていました。そのため、バリデーターとマネージド Bean では、トリミングされていない値を取得しています。検証フェーズの前に実行できる方法はありますか、またはこのロジックをどこかに実装する必要がありますか?

4

1 に答える 1

1

このロジックは、decode()メソッドまたは簡単にsetSubmittedValue().

@Override
public void setSubmittedValue(UIComponent component, Object value) {
    if (value instanceof String) {
        value = ((String) value).trim();
    }

    super.setSubmittedValue(component, value);
}

ちなみに、この Mojarra 固有のレンダラー拡張機能に代わる、より簡単で実装に依存しない代替手段は でした@FacesConverter(forClass=String)

于 2012-11-08T12:41:54.797 に答える