当用户决定将表单中的字段保留为空时,Apache Struts将空String
绑定为ActionForm
中属性的值。有没有办法全局修改行为并选择null
而不是空String
?
我知道Spring MVC完全相同,但也有StringTrimmerEditor可以注册为属性编辑器来修剪字符串null
。
答案 0 :(得分:3)
一个可能的解决方案 - 允许所有String字段的单个转换入口点 - 可以是注册自定义转换器,但不能使用Struts但使用BeanUtils。
为了将请求参数映射到表单属性,Struts使用populate method of its RequestUtils class。这个类反过来使用BeanUtils
实现来完成它的工作。
简单的流程就像Struts'RequestUtils>之类的东西。 BeanUtils> BeanUtilsBean> ConvertUtils> ConvertUtilsBean> Converter
有趣的是,还有一个StringConverter从String转换为... aaaaaa ... String!
ConvertUtils class has a register方法,您可以使用它来注册转换器,覆盖现有的转换器。这意味着您可以自己编写自定义字符串转换器,它为空字符串返回null,然后您可以等待Struts应用程序完全加载,这样您就不会感到意外(即确保您的转换器是最后一个注册类型{{1} })。
加载应用程序后,您将介入并使用您自己的实现覆盖默认的String转换器。例如,您可以使用ServletContextListener执行此操作,并使用String
方法调用ConvertUtils.register(...)
。
然后,您可以在contextInitialized
和should be good to go中配置监听器。
答案 1 :(得分:1)
我认为您可以使用自己的BeanUtils实现,覆盖类org.apache.commons.beanutils.converters.AbstractConverter和org.apache.commons.beanutils.converters.StringConverter
答案 2 :(得分:1)
在web.xml中使用以下代码
<init-param>
<param-name>convertNull</param-name>
<param-value>true</param-value>
</init-param>
答案 3 :(得分:0)
默认情况下,将ActionForm中的字符串值声明为NULL
。
Eg: private String str = null;
编辑:解决方案是这样的。 我认为对于该属性你有setter和getter方法,在getter方法中检查值是否为空,然后你explisitly设置为null值。
答案 4 :(得分:0)
请参阅Apache的StringUtils.stripToNull()
方法。
至于配置,Struts没有给我们这个功能(我不记得)。我建议从reset()
覆盖ActionForm
方法,但在控制器重新填充表单bean之前调用它。
答案 5 :(得分:0)
Cf http://struts.apache.org/development/1.x/userGuide/configuration.html for convertNull; - )
convertNull - 填充表单时强制模拟1.0版本的行为。如果设置为“true”,则数字Java包装器类类型(如java.lang.Integer)将默认为null(而不是0)。 (自1.1版开始)[false]
答案 6 :(得分:0)
这是一个有点老问题,但我通过实施另一种解决方案解决了这个问题(我想以更简单的方式)。
我实现了一个TypeConverter
来将空字符串转换为null。
需要两个文件:
转换器。
public class StringEmptyToNullConverter implements TypeConverter {
private static final Logger log = LoggerFactory.getLogger(StringEmptyToNullConverter.class);
@Override
public Object convertValue(Map arg0, Object arg1, Member member, String arg3, Object obj, Class arg5) {
String[] value = (String[]) obj;
if (value == null || value[0] == null || value[0].isEmpty()) {
logDebug("is null or empty: return null");
return null;
}
logDebug("not null and not empty: return '{}'", value[0]);
return value[0];
}
private void logDebug(String msg, Object... obj) {
if (log.isDebugEnabled()) {
log.debug(msg, obj);
}
}
}
寄存器名为xwork-conversion.properties
。您必须将此文件放在Java路径中。
# syntax: <type> = <converterClassName>
java.lang.String = StringEmptyToNullConverter
请参阅struts converter documentation
答案 7 :(得分:0)
Struts 2为拦截器提供了一个很好的机制,我认为这比拦截BeanUtils
更安全,更容易。这是我使用的代码,基于Cimballi's Blog但编辑为在Java 7中编译(原始版本是2009年):
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
public class RemoveEmptyParametersInterceptor implements Interceptor {
public RemoveEmptyParametersInterceptor() {
super();
}
/**
* @see com.opensymphony.xwork2.interceptor.Interceptor#destroy()
*/
public void destroy() {
// Nothing to do.
}
/**
* @see com.opensymphony.xwork2.interceptor.Interceptor#init()
*/
public void init() {
// Nothing to do.
}
public String intercept(final ActionInvocation invocation) throws Exception {
final String result;
final ActionContext actionContext = invocation.getInvocationContext();
final Map<String, Object> parameters = actionContext.getParameters();
if (parameters == null) {
// Nothing to do.
} else {
final Collection<String> parametersToRemove = new ArrayList<String>();
for (final Map.Entry entry : parameters.entrySet()) {
final Object object = entry.getValue();
if (object instanceof String) {
final String value = (String) object;
if (StringUtils.isEmpty(value)) {
parametersToRemove.add((String) entry.getKey());
}
} else if (object instanceof String[]) {
final String[] values = (String[]) object;
final Object[] objects =
ArrayUtils.removeElement(values, "");
if (objects.length == 0) {
parametersToRemove.add((String) entry.getKey());
}
} else {
throw new IllegalArgumentException();
}
}
for (final String parameterToRemove : parametersToRemove) {
parameters.remove(parameterToRemove);
}
}
result = invocation.invoke();
return result;
}
}
以下是我在struts.xml文件中使用它的方法:
<package name="webdefault" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="removeEmptyParameters" class="com.sentrylink.web.struts.RemoveEmptyParametersInterceptor"/>
<interceptor-stack name="webStack">
<interceptor-ref name="removeEmptyParameters"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="webStack"/>
...
</package>
有人向我指出,原始问题中的ActionForm是一个Struts 1约定(此问题已被正确标记),但由于Google仍然带有一个Struts 2查询,我希望这个答案对某人有用其他