【问题标题】:Trimming inputs in JBoss Seam在 JBoss Seam 中修剪输入
【发布时间】:2010-11-26 00:00:27
【问题描述】:

我正在使用 JBoss Seam 2.2.0 制作一个 Web 应用程序,并且我想在接收输入之前修剪我的输入,甚至在 Hibernate Bean 验证阶段之前。这可能吗?

我看到someone 使用PhaseListener 来执行相同的功能。这是最好的方法吗?

【问题讨论】:

标签: java jsf jboss jakarta-ee seam


【解决方案1】:

我为此使用了转换器。效果很好。

页面:

<h:inputText value="#{myBean.myValue}" converter="#{stringTrimConverter}"/>

代码:

@Name("stringTrimConverter")
@BypassInterceptors
@Converter
public class StringTrimConverter implements javax.faces.convert.Converter {

    public Object getAsObject(FacesContext context, UIComponent cmp, String value) {

        if(StringUtils.isBlank(value)) {
            return null;
        } else {
            return value;
        }
    }

    public String getAsString(FacesContext context, UIComponent cmp, Object value) {

        if(value != null) {
            return value.toString().trim();
        } 
        return null;
    }

}

【讨论】:

  • 谢谢。这当然是一个可能的解决方案,但我必须手动将转换器添加到每个输入字段。我希望有一个更简单的方法。
【解决方案2】:

一个建议是在用户更改输入值后修剪 Javascript 中的文本:

<h:inputText ... onchange="this.value = trim(this.value);"/>

使用Javascript函数:

function trim(myString) {
    return myString.replace(/^\s+/g,'').replace(/\s+$/g,'');
}


编辑,关于您的评论:

我建议的解决方案是最好的方法,因为它是在客户端完成的。但是,正如您在评论中所说,如果客户端的浏览器不允许 Javascript,它将无法工作。 As shown here95% 的用户在他们的浏览器上激活了 Javascript(这是在 2008 年 1 月!)。

但是,如果你真的需要不支持任何 Javascript 浏览器,我建议你确实实现 PhaseListener 解决方案。


编辑2

Damo 提出的带有Convertor 的解决方案也有效,但您需要为每个 输入指定转换器,而PhaseListener 不需要,即您需要始终为您的所有输入添加converter="#{stringTrimConverter}"

【讨论】:

  • 谢谢。这是部分解决方案,但不适用于禁用 JavaScript 的客户端。
  • 谢谢。许多浏览器都支持 JavaScript,但那是在桌面上。一些手机浏览器不支持 JavaScript(尽管很多都支持)。另一方面,我不喜欢信任从客户端发送的值,所以我更愿意在客户端和服务器端都这样做。
  • 至于转换器,您为什么说他们会在 验证之后进行修剪?我认为 JSF 生命周期另有规定。如果我错了,请纠正我。
  • 是的,抱歉,转换是在任何验证之前进行的。我再次编辑了我的答案。正如我所解释的,转换器解决方案将起作用,但您必须指定要用于应用程序中每个输入的转换器(方法或转换器 ID)...
【解决方案3】:

也许更好的方法是扩展&lt;h:inputText&gt;,创建您自己的组件,该组件与&lt;h:inputText&gt; 几乎相同,但默认情况下会修剪结果。

在我看来,inputText 中应该有一个默认修剪的属性,即:

<h:inputText value="#{myBean.text}" trim="true"/>

更新:

好的,下面介绍如何创建一个修剪 inputText 字段的组件。 但是请注意,我还没有测试过代码,所以我不能 100% 确定它会工作,但应该会。

faces-config.xml

添加你的组件

<component>
  <component-type>foo.InputControlComponent</component-type>
  <component-class>my.package.foo.InputControl</component-class>
</component>

创建WEB-INF/foo.taglib.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
   <namespace>http://whatever.com/foo</namespace>
    <tag>
        <tag-name>inputControl</tag-name>
        <component>
            <component-type>foo.InputControlComponent</component-type>
        </component>
    </tag>
 </facelet-taglib>

web.xml

<context-param>
  <param-name>facelets.LIBRARIES</param-name>
  <param-value>/WEB-INF/foo.taglib.xml</param-value>
</context-param>

InputControl.java

public class InputControl extends UIPanel {

    public InputControl() {
        super();
    }

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

        // Encode recursively
        if (comp.isRendered() && comp.getChildCount() > 0)
            childrenEncodeBegin(context, comp.getChildren());
    }

    }

    public void encodeBegin(FacesContext context) throws IOException {
        if (getChildren() != null)
            childrenEncodeBegin(context, getChildren());
    }
}

现在在你的 xhtml 中你可以像这样使用它:

<foo:inputControl>
  <ui:include src="myForm.xhtml"/>
</foo:inputControl> 

【讨论】:

  • 这看起来是个好主意。您能否添加一个有关如何操作的示例?
猜你喜欢
  • 1970-01-01
  • 2010-10-31
  • 2012-01-12
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
相关资源
最近更新 更多