com.opensymphony.xwork2.validator.ValidationInterceptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xwork Show documentation
Show all versions of xwork Show documentation
XWork is an command-pattern framework that is used to power WebWork
as well as other applications. XWork provides an Inversion of Control
container, a powerful expression language, data type conversion,
validation, and pluggable configuration.
/*
* Copyright (c) 2002-2007 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.xwork2.validator;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.Validateable;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
import com.opensymphony.xwork2.interceptor.PrefixMethodInvocationUtil;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
/**
*
*
* This interceptor runs the action through the standard validation framework, which in turn checks the action against
* any validation rules (found in files such as ActionClass-validation.xml) and adds field-level and action-level
* error messages (provided that the action implements {@link com.opensymphony.xwork2.ValidationAware}). This interceptor
* is often one of the last (or second to last) interceptors applied in a stack, as it assumes that all values have
* already been set on the action.
*
* This interceptor does nothing if the name of the method being invoked is specified in the excludeMethods
* parameter. excludeMethods accepts a comma-delimited list of method names. For example, requests to
* foo!input.action and foo!back.action will be skipped by this interceptor if you set the
* excludeMethods parameter to "input, back".
*
*
*
* The workflow of the action request does not change due to this interceptor. Rather,
* this interceptor is often used in conjuction with the workflow interceptor.
*
*
*
* NOTE: As this method extends off MethodFilterInterceptor, it is capable of
* deciding if it is applicable only to selective methods in the action class. See
* MethodFilterInterceptor
for more info.
*
*
*
* Interceptor parameters:
*
*
*
*
*
* - alwaysInvokeValidate - Defaults to true. If true validate() method will always
* be invoked, otherwise it will not.
*
* - programmatic - Defaults to true. If true and the action is Validateable call validate(),
* and any method that starts with "validate".
*
*
* - declarative - Defaults to true. Perform validation based on xml or annotations.
*
*
*
*
*
* Extending the interceptor:
*
*
*
*
*
* There are no known extension points for this interceptor.
*
*
*
* Example code:
*
*
*
*
* <action name="someAction" class="com.examples.SomeAction">
* <interceptor-ref name="params"/>
* <interceptor-ref name="validation"/>
* <interceptor-ref name="workflow"/>
* <result name="success">good_result.ftl</result>
* </action>
*
* <-- in the following case myMethod of the action class will not
* get validated -->
* <action name="someAction" class="com.examples.SomeAction">
* <interceptor-ref name="params"/>
* <interceptor-ref name="validation">
* <param name="excludeMethods">myMethod</param>
* </interceptor-ref>
* <interceptor-ref name="workflow"/>
* <result name="success">good_result.ftl</result>
* </action>
*
* <-- in the following case only annotated methods of the action class will
* be validated -->
* <action name="someAction" class="com.examples.SomeAction">
* <interceptor-ref name="params"/>
* <interceptor-ref name="validation">
* <param name="validateAnnotatedMethodOnly">true</param>
* </interceptor-ref>
* <interceptor-ref name="workflow"/>
* <result name="success">good_result.ftl</result>
* </action>
*
*
*
*
*
* @author Jason Carreira
* @author Rainer Hermanns
* @author Alexandru Popescu
* @see ActionValidatorManager
* @see com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor
*/
public class ValidationInterceptor extends MethodFilterInterceptor {
private boolean validateAnnotatedMethodOnly;
private ActionValidatorManager actionValidatorManager;
private static final Logger LOG = LoggerFactory.getLogger(DefaultWorkflowInterceptor.class);
private final static String VALIDATE_PREFIX = "validate";
private final static String ALT_VALIDATE_PREFIX = "validateDo";
private boolean alwaysInvokeValidate = true;
private boolean programmatic = true;
private boolean declarative = true;
@Inject
public void setActionValidatorManager(ActionValidatorManager mgr) {
this.actionValidatorManager = mgr;
}
/**
* Determines if {@link Validateable}'s validate()
should be called,
* as well as methods whose name that start with "validate". Defaults to "true".
*
* @param programmatic true then validate()
is invoked.
*/
public void setProgrammatic(boolean programmatic) {
this.programmatic = programmatic;
}
/**
* Determines if validation based on annotations or xml should be performed. Defaults
* to "true".
*
* @param declarative true then perform validation based on annotations or xml.
*/
public void setDeclarative(boolean declarative) {
this.declarative = declarative;
}
/**
* Determines if {@link Validateable}'s validate()
should always
* be invoked. Default to "true".
*
* @param alwaysInvokeValidate true then validate()
is always invoked.
*/
public void setAlwaysInvokeValidate(String alwaysInvokeValidate) {
this.alwaysInvokeValidate = Boolean.parseBoolean(alwaysInvokeValidate);
}
/**
* Gets if validate()
should always be called or only per annotated method.
*
* @return true to only validate per annotated method, otherwise false to always validate.
*/
public boolean isValidateAnnotatedMethodOnly() {
return validateAnnotatedMethodOnly;
}
/**
* Determine if validate()
should always be called or only per annotated method.
* Default to false.
*
* @param validateAnnotatedMethodOnly true to only validate per annotated method, otherwise false to always validate.
*/
public void setValidateAnnotatedMethodOnly(boolean validateAnnotatedMethodOnly) {
this.validateAnnotatedMethodOnly = validateAnnotatedMethodOnly;
}
/**
* Gets the current action and its context and delegates to {@link ActionValidatorManager} proper validate method.
*
* @param invocation the execution state of the Action.
* @throws Exception if an error occurs validating the action.
*/
protected void doBeforeInvocation(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
ActionProxy proxy = invocation.getProxy();
String context = proxy.getActionName();
String method = proxy.getMethod();
if (log.isDebugEnabled()) {
log.debug("Validating "
+ invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName() + " with method "+ method +".");
}
if (declarative) {
if (validateAnnotatedMethodOnly) {
actionValidatorManager.validate(action, context, method);
} else {
actionValidatorManager.validate(action, context);
}
}
if (action instanceof Validateable && programmatic) {
// keep exception that might occured in validateXXX or validateDoXXX
Exception exception = null;
Validateable validateable = (Validateable) action;
if (LOG.isDebugEnabled()) {
LOG.debug("Invoking validate() on action "+validateable);
}
try {
PrefixMethodInvocationUtil.invokePrefixMethod(
invocation,
new String[] { VALIDATE_PREFIX, ALT_VALIDATE_PREFIX });
}
catch(Exception e) {
// If any exception occurred while doing reflection, we want
// validate() to be executed
LOG.warn("an exception occured while executing the prefix method", e);
exception = e;
}
if (alwaysInvokeValidate) {
validateable.validate();
}
if (exception != null) {
// rethrow if something is wrong while doing validateXXX / validateDoXXX
throw exception;
}
}
}
protected String doIntercept(ActionInvocation invocation) throws Exception {
doBeforeInvocation(invocation);
return invocation.invoke();
}
}