问题的情况是这个
1)我们将struts字段值映射到dtos。 dtos包含再次显示在屏幕上的整数字段。
2)现在我输入一个不正确的值,它给出了整数字段的转换错误。
3)在那个时候我决定退出页面(即按取消),我收到转换错误。这是因为每次都会调用StrutsConversionErrorInterceptor。
当我调用特定方法时,有没有办法可以跳过strutsConversionErrorInterceptor,就像我们可以使用excludeMethods跳过验证一样
答案 0 :(得分:0)
是的,你可以跳过调用拦截器。
只需从struts.xml文件中的操作定义中删除拦截器定义即可。
即,删除<interceptor-ref name="conversionError"/>
主要是这个拦截器将ActionContext的conversionErrors映射中发现的任何错误添加为字段错误(假设该操作实现了ValidationAware)。此外,包含验证错误的任何字段都会保存其原始值,以便对该值的任何后续请求都返回原始值而不是操作中的值。这很重要,因为如果提交值“abc”并且无法转换为int,我们想再次显示原始字符串(“abc”)而不是int值(可能为0,这很有意义)给用户)。
删除此拦截器后,如果struts无法使用对象的参数(即从string到int)映射字段,则会抛出结果输入操作错误。
答案 1 :(得分:0)
使用此代码覆盖Struts的StrutsConversionErrorInterceptor ...
public class MyConversionErrorInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 1L;
public static final String ORIGINAL_PROPERTY_OVERRIDE = "original.property.override";
protected Object getOverrideExpr(ActionInvocation invocation, Object value) {
ValueStack stack = invocation.getStack();
try {
stack.push(value);
return "'" + stack.findValue("top", String.class) + "'";
} finally {
stack.pop();
}
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext invocationContext = invocation.getInvocationContext();
Map<String, Object> conversionErrors = invocationContext.getConversionErrors();
ValueStack stack = invocationContext.getValueStack();
HashMap<Object, Object> fakie = null;
BaseAction baseAction = (BaseAction) invocation.getAction();
String buttonName = baseAction.getButtonName();
for (Map.Entry<String, Object> entry : conversionErrors.entrySet()) {
String propertyName = entry.getKey();
Object value = entry.getValue();
if (shouldAddError(propertyName, value)) {
String message = XWorkConverter.getConversionErrorMessage(propertyName, stack);
Object action = invocation.getAction();
if (action instanceof ValidationAware) {
ValidationAware va = (ValidationAware) action;
if(buttonName.equalsIgnoreCas("Next")){
va.addFieldError(propertyName, message);
}
}
if (fakie == null) {
fakie = new HashMap<Object, Object>();
}
if(buttonName.equalsIgnoreCas("Next")){
fakie.put(propertyName, getOverrideExpr(invocation, value));
}
}
}
if (fakie != null) {
// if there were some errors, put the original (fake) values in
// place right before the result
stack.getContext().put(ORIGINAL_PROPERTY_OVERRIDE, fakie);
invocation.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation invocation, String resultCode) {
Map<Object, Object> fakie = (Map<Object, Object>) invocation.getInvocationContext().get(ORIGINAL_PROPERTY_OVERRIDE);
if (fakie != null) {
invocation.getStack().setExprOverrides(fakie);
}
}
});
}
return invocation.invoke();
}
protected boolean shouldAddError(String propertyName, Object value) {
if (value == null) {
return false;
}
if ("".equals(value)) {
return false;
}
if (value instanceof String[]) {
String[] array = (String[]) value;
if (array.length == 0) {
return false;
}
if (array.length > 1) {
return true;
}
String str = array[0];
if ("".equals(str)) {
return false;
}
}
return true;
}
}
您可以指定要激活验证的按钮名称。在上面的代码中,我在代码中使用了“Next”
如果(buttonName.equalsIgnoreCas( “下一个”))强>
答案 2 :(得分:0)
这似乎是处理此方案的更好方法 - 使用Conversion Validator
。 Repopulating Field upon conversion Error
部分非常有用:
http://struts.apache.org/2.0.14/docs/conversion-validator.html