Object action = invocation.getAction();
        if (action instanceof ValidationAware) {
            ValidationAware va = (ValidationAware) action;
            if(va.hasFieldErrors()|| va.hasActionErrors()){
            	return "input";
            }
        }关于非字段验证:不是针对某一字段的验证
 <!-- 测试非字段验证 -->
      <validator type="expression">
         <param name="expression"><![CDATA[password = password2]]></param>
         <message>Password id not equals to password2 </message>
      </validator>、
显示非字段验证的错误消息,使用s:actionerror标签:<s:actionerror/><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<constant name="struts.custom.i18n.resources" value="i18n"></constant>
    <package name="default" namespace="/" extends="struts-default">
		<action name="testValidateion" class="com.wul.app.TestValidationAction">
			<result>/success.jsp</result>
			
			<!-- 若验证失败转向的input -->
			<result name="input">/validation.jsp</result>
		</action>
		<action name="testValidateion2" class="com.wul.app.TestValidationAction">
			<result>/success.jsp</result>
			
			<!-- 若验证失败转向的input -->
			<result name="input">/validation2.jsp</result>
		</action>
    </package>
</struts>
i18n.properties#error.int=wul\u56FD\u9645\u5316:Age needs to be between ${min} and ${max}
#error.countint=count needs to be between ${min} and ${max}
#error.int=${fieldName} needs to be between ${min} and ${max}
error.int=${getText(fieldName)} needs to be between ${min} and ${max}
age=\u5E74\u9F84
count=\u6570\u91CFConversionErrorInterceptor.java/*
 * Copyright 2002-2007,2009 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ValidationAware;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.commons.lang3.StringEscapeUtils;
import java.util.HashMap;
import java.util.Map;
/**
 * <!-- START SNIPPET: description -->
 * ConversionErrorInterceptor adds conversion errors from the ActionContext to the Action's field errors.
 *
 * <p/>
 * This interceptor adds any error found in the {@link ActionContext}'s conversionErrors map as a field error (provided
 * that the action implements {@link ValidationAware}). In addition, any field that contains a validation error has its
 * original value saved such that any subsequent requests for that value return the original value rather than the value
 * in the action. This is important because if the value "abc" is submitted and can't be converted to an int, we want to
 * display the original string ("abc") again rather than the int value (likely 0, which would make very little sense to
 * the user).
 *
 *
 * <!-- END SNIPPET: description -->
 *
 * <p/> <u>Interceptor parameters:</u>
 *
 * <!-- START SNIPPET: parameters -->
 *
 * <ul>
 *
 * <li>None</li>
 *
 * </ul>
 *
 * <!-- END SNIPPET: parameters -->
 *
 * <p/> <u>Extending the interceptor:</u>
 *
 * <p/>
 *
 * <!-- START SNIPPET: extending -->
 *
 * Because this interceptor is not web-specific, it abstracts the logic for whether an error should be added. This
 * allows for web-specific interceptors to use more complex logic in the {@link #shouldAddError} method for when a value
 * has a conversion error but is null or empty or otherwise indicates that the value was never actually entered by the
 * user.
 *
 * <!-- END SNIPPET: extending -->
 *
 * <p/> <u>Example code:</u>
 *
 * <pre>
 * <!-- START SNIPPET: example -->
 * <action name="someAction" class="com.examples.SomeAction">
 *     <interceptor-ref name="params"/>
 *     <interceptor-ref name="conversionError"/>
 *     <result name="success">good_result.ftl</result>
 * </action>
 * <!-- END SNIPPET: example -->
 * </pre>
 *
 * @author Jason Carreira
 */
public class ConversionErrorInterceptor extends AbstractInterceptor {
    public static final String ORIGINAL_PROPERTY_OVERRIDE = "original.property.override";
    protected Object getOverrideExpr(ActionInvocation invocation, Object value) {
        return escape(value);
    }
    protected String escape(Object value) {
        return "\"" + StringEscapeUtils.escapeJava(String.valueOf(value)) + "\"";
    }
    @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;
        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;
                    va.addFieldError(propertyName, message);
                }
                if (fakie == null) {
                    fakie = new HashMap<Object, Object>();
                }
                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);
                    }
                }
            });
        }
        ////修改添加//////////
        Object action = invocation.getAction();
        if (action instanceof ValidationAware) {
            ValidationAware va = (ValidationAware) action;
            if(va.hasFieldErrors()|| va.hasActionErrors()){
            	return "input";
            }
        }
        
        ////////////////
        return invocation.invoke();
    }
    protected boolean shouldAddError(String propertyName, Object value) {
        return true;
    }
}
TestValidationAction.javapackage com.wul.app;
import com.opensymphony.xwork2.ActionSupport;
public class TestValidationAction extends ActionSupport {
	
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int age;
	
	private String password;
	private String password2;
	
	//private int count;//若想不回显
	//改为
	private Integer count;
	
	
	public Integer getCount() {
		return count;
	}
	public void setCount(Integer count) {
		this.count = count;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getPassword2() {
		return password2;
	}
	public void setPassword2(String password2) {
		this.password2 = password2;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	@Override
	public String execute() throws Exception {
		System.out.println("age:"+age);
		return SUCCESS;
	}
}
TestValidationAction-testValidateion-validation.xml<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator 1.0.2//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
<validators>
	<!-- 针对age属性进行验证,基于字段的验证 -->
	 <field name="age">
         <field-validator type="int">
             <param name="min">20</param>
             <param name="max">50</param>
           <!--<message>wul:Age needs to be between ${min} and ${max}</message> -->
             <message key="error.int"></message>
         </field-validator>
     </field>
</validators>
TestValidationAction-testValidateion2-validation.xml<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator 1.0.2//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
<validators>
	<!-- 针对age属性进行验证,基于字段的验证 -->
	 <field name="age">
	 	<!-- 设置短路验证:若当前验证没有通过,则不再进行下面的验证 -->
	 	<field-validator type="conversion" short-circuit="true">
	 		<message>Conversion Error Occurred</message>
	 	</field-validator>
         <field-validator type="int">
             <param name="min">1</param>
             <param name="max">130</param>
           <!--<message>wul:Age needs to be between ${min} and ${max}</message> -->
             <message key="error.int"></message>
         </field-validator>
     </field>
	
	<field name="count">
		 <field-validator type="int">
             <param name="min">1</param>
             <param name="max">10</param>
            <!-- <message key="error.countint"></message>--> 
             <message key="error.int"></message>
         </field-validator>
	</field>
	
	 <!-- 测试非字段验证 -->
      <validator type="expression">
         <param name="expression"><![CDATA[password = password2]]></param>
         <message>Password id not equals to password2 </message>
      </validator>
</validators>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="s"  uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
	<s:debug></s:debug>
	
	<!-- 要求年龄必须在20-50之间 -->
	<s:form action="testValidateion" theme="simple">
	 <s:textfield name="age" label="Age"></s:textfield>
	 
	 <s:fielderror name="age"></s:fielderror>
	 ${fieldErrors.age[0] }
	 
	 <s:submit></s:submit>
	</s:form>
</body>
</html><%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <s:debug></s:debug> <s:actionerror/> <!-- 要求年龄必须在1-130之间 --> <s:form action="testValidateion2" theme="simple"> <s:textfield name="age" label="Age"></s:textfield> <s:fielderror fieldName="age"></s:fielderror> <s:password name="password" label="password"></s:password> <s:password name="password2" label="password2"></s:password> <s:textfield name="count" label="Count"></s:textfield> <s:fielderror fieldName="count"></s:fielderror> <s:submit></s:submit> </s:form> </body> </html>success.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> success </body> </html>
原文:http://blog.csdn.net/mrwuyi/article/details/51516243