mirror of
https://github.com/apache/struts.git
synced 2026-08-07 07:37:20 +00:00
Form.getValidators does not respect validateAnnotatedMethodOnly flag
WW-4139 removed method name from getValidators call. While this works fine for a case mentioned in that ticket it fails to account for a case when dynamicMethodCalls and validateAnnotatedMethodOnly are used. Without method name actionValidatorManager.getValidators returns all validators defined for a given field. Expected behavior for dynamicMethodCalls with validateAnnotatedMethodOnly case is to return validators for a given field defined at the method level.
This commit is contained in:
@@ -35,6 +35,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.views.annotations.StrutsTag;
|
||||
import org.apache.struts2.views.annotations.StrutsTagAttribute;
|
||||
import org.apache.struts2.views.jsp.TagUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@@ -277,7 +278,12 @@ public class Form extends ClosingUIBean {
|
||||
ActionMapping mapping = actionMapper.getMappingFromActionName(formActionValue);
|
||||
String actionName = mapping.getName();
|
||||
|
||||
List<Validator> actionValidators = actionValidatorManager.getValidators(actionClass, actionName);
|
||||
String methodName = null;
|
||||
if (isValidateAnnotatedMethodOnly(actionName)) {
|
||||
methodName = mapping.getMethod();
|
||||
}
|
||||
|
||||
List<Validator> actionValidators = actionValidatorManager.getValidators(actionClass, actionName, methodName);
|
||||
List<Validator> validators = new ArrayList<>();
|
||||
|
||||
findFieldValidators(name, actionClass, actionName, actionValidators, validators, "");
|
||||
@@ -285,6 +291,23 @@ public class Form extends ClosingUIBean {
|
||||
return validators;
|
||||
}
|
||||
|
||||
private boolean isValidateAnnotatedMethodOnly(String actionName) {
|
||||
RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration();
|
||||
String actionNamespace = TagUtils.buildNamespace(actionMapper, stack, request);
|
||||
ActionConfig actionConfig = runtimeConfiguration.getActionConfig(actionNamespace, actionName);
|
||||
|
||||
if (actionConfig != null) {
|
||||
List<InterceptorMapping> interceptors = actionConfig.getInterceptors();
|
||||
for (InterceptorMapping interceptorMapping : interceptors) {
|
||||
if (ValidationInterceptor.class.isInstance(interceptorMapping.getInterceptor())) {
|
||||
ValidationInterceptor validationInterceptor = (ValidationInterceptor) interceptorMapping.getInterceptor();
|
||||
return validationInterceptor.isValidateAnnotatedMethodOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void findFieldValidators(String name, Class actionClass, String actionName,
|
||||
List<Validator> validatorList, List<Validator> resultValidators, String prefix) {
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ package org.apache.struts2;
|
||||
import com.opensymphony.xwork2.Action;
|
||||
import com.opensymphony.xwork2.ActionSupport;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
|
||||
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
|
||||
import com.opensymphony.xwork2.validator.annotations.Validations;
|
||||
import com.opensymphony.xwork2.validator.annotations.ValidatorType;
|
||||
import org.apache.struts2.views.jsp.ui.User;
|
||||
|
||||
import java.util.*;
|
||||
@@ -177,6 +181,26 @@ public class TestAction extends ActionSupport {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Validations(
|
||||
requiredFields = {
|
||||
@RequiredFieldValidator(type = ValidatorType.SIMPLE, fieldName = "status", message = "You must enter a value for field.")
|
||||
},
|
||||
requiredStrings = {
|
||||
@RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "result", message = "You must enter a value for field.")
|
||||
}
|
||||
)
|
||||
public String annotatedExecute1() throws Exception {
|
||||
return Action.SUCCESS;
|
||||
}
|
||||
@Validations(
|
||||
requiredFields = {
|
||||
@RequiredFieldValidator(type = ValidatorType.SIMPLE, fieldName = "status", message = "You must enter a value for field.")
|
||||
}
|
||||
)
|
||||
public String annotatedExecute2() throws Exception {
|
||||
return Action.SUCCESS;
|
||||
}
|
||||
|
||||
public String executeThrowsException() throws Exception {
|
||||
throw new StrutsException("something went wrong!");
|
||||
}
|
||||
|
||||
@@ -26,35 +26,76 @@ import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.ActionProxy;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.config.entities.InterceptorMapping;
|
||||
import com.opensymphony.xwork2.validator.ValidationInterceptor;
|
||||
import com.opensymphony.xwork2.validator.validators.RequiredFieldValidator;
|
||||
import com.opensymphony.xwork2.validator.validators.RequiredStringValidator;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
|
||||
import org.apache.struts2.TestAction;
|
||||
import org.apache.struts2.views.jsp.AbstractUITagTest;
|
||||
import org.easymock.EasyMock;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <code>FormTest</code>
|
||||
*
|
||||
*/
|
||||
public class FormTest extends AbstractUITagTest {
|
||||
|
||||
private ValidationInterceptor validationInterceptor;
|
||||
|
||||
public void testTestFormGetValidators() {
|
||||
Form form = new Form(stack, request, response);
|
||||
checkValidateAnnotatedMethodOnly(false, null, 1, 2, 1);
|
||||
}
|
||||
public void testAnnotatedFormGetValidators() {
|
||||
checkValidateAnnotatedMethodOnly(true, null, 1, 2, 1);
|
||||
}
|
||||
public void testValidateAnnotatedMethodOnlyGetValidators1() {
|
||||
checkValidateAnnotatedMethodOnly(true, "annotatedExecute1", 0, 1, 1);
|
||||
}
|
||||
public void testValidateAnnotatedMethodOnlyGetValidators2() {
|
||||
checkValidateAnnotatedMethodOnly(true, "annotatedExecute2", 0, 1, 0);
|
||||
}
|
||||
|
||||
private void checkValidateAnnotatedMethodOnly(boolean validateAnnotatedMethodOnly, String methodName,
|
||||
int expectedFooValidators, int expectedStatusValidators, int expectedResultValidators) {
|
||||
Form form = new Form(stack, request, response);
|
||||
container.inject(form);
|
||||
form.getParameters().put("actionClass", TestAction.class);
|
||||
form.setAction("actionName");
|
||||
|
||||
form.setAction("actionName" + (methodName != null ? "!" + methodName : ""));
|
||||
validationInterceptor.setValidateAnnotatedMethodOnly(validateAnnotatedMethodOnly);
|
||||
|
||||
List v = form.getValidators("foo");
|
||||
assertEquals(1, v.size());
|
||||
assertEquals(RequiredFieldValidator.class, v.get(0).getClass());
|
||||
}
|
||||
assertEquals(expectedFooValidators, v.size());
|
||||
for (Object validator : v) {
|
||||
assertEquals(RequiredFieldValidator.class, validator.getClass());
|
||||
}
|
||||
|
||||
v = form.getValidators("status");
|
||||
assertEquals(expectedStatusValidators, v.size());
|
||||
for (Object validator : v) {
|
||||
assertEquals(RequiredFieldValidator.class, validator.getClass());
|
||||
}
|
||||
|
||||
v = form.getValidators("result");
|
||||
assertEquals(expectedResultValidators, v.size());
|
||||
for (Object validator : v) {
|
||||
assertEquals(RequiredStringValidator.class, validator.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
validationInterceptor = new ValidationInterceptor();
|
||||
validationInterceptor.setIncludeMethods("*");
|
||||
|
||||
ActionConfig config = new ActionConfig.Builder("", "name", "").build();
|
||||
ActionConfig config = new ActionConfig.Builder("", "name", "")
|
||||
.addInterceptor(new InterceptorMapping("validationInterceptor", validationInterceptor))
|
||||
.build();
|
||||
ActionInvocation invocation = EasyMock.createNiceMock(ActionInvocation.class);
|
||||
ActionProxy proxy = EasyMock.createNiceMock(ActionProxy.class);
|
||||
|
||||
@@ -66,6 +107,11 @@ public class FormTest extends AbstractUITagTest {
|
||||
|
||||
EasyMock.replay(invocation);
|
||||
EasyMock.replay(proxy);
|
||||
|
||||
Map<String, ActionConfig> defaultNamespace = configuration.getRuntimeConfiguration().getActionConfigs().get("");
|
||||
defaultNamespace.put("actionName", config);
|
||||
|
||||
((DefaultActionMapper) container.getInstance(ActionMapper.class)).setAllowDynamicMethodCalls("true");
|
||||
|
||||
ActionContext.getContext().setActionInvocation(invocation);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user