【发布时间】:2010-11-26 00:00:27
【问题描述】:
我正在使用 JBoss Seam 2.2.0 制作一个 Web 应用程序,并且我想在接收输入之前修剪我的输入,甚至在 Hibernate Bean 验证阶段之前。这可能吗?
我看到someone 使用PhaseListener 来执行相同的功能。这是最好的方法吗?
【问题讨论】:
标签: java jsf jboss jakarta-ee seam
我正在使用 JBoss Seam 2.2.0 制作一个 Web 应用程序,并且我想在接收输入之前修剪我的输入,甚至在 Hibernate Bean 验证阶段之前。这可能吗?
我看到someone 使用PhaseListener 来执行相同的功能。这是最好的方法吗?
【问题讨论】:
标签: java jsf jboss jakarta-ee seam
我为此使用了转换器。效果很好。
页面:
<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;
}
}
【讨论】:
一个建议是在用户更改输入值后修剪 Javascript 中的文本:
<h:inputText ... onchange="this.value = trim(this.value);"/>
使用Javascript函数:
function trim(myString) {
return myString.replace(/^\s+/g,'').replace(/\s+$/g,'');
}
我建议的解决方案是最好的方法,因为它是在客户端完成的。但是,正如您在评论中所说,如果客户端的浏览器不允许 Javascript,它将无法工作。 As shown here,95% 的用户在他们的浏览器上激活了 Javascript(这是在 2008 年 1 月!)。
但是,如果你真的需要不支持任何 Javascript 浏览器,我建议你确实实现 PhaseListener 解决方案。
Damo 提出的带有Convertor 的解决方案也有效,但您需要为每个 输入指定转换器,而PhaseListener 不需要,即您需要始终为您的所有输入添加converter="#{stringTrimConverter}"。
【讨论】:
也许更好的方法是扩展<h:inputText>,创建您自己的组件,该组件与<h:inputText> 几乎相同,但默认情况下会修剪结果。
在我看来,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>
【讨论】: