例如我有以下内容:
struts.xml:
<action name="personForm">
<result>/jsp/personForm.jsp</result>
</action>
<action name="savePerson">
<result>/jsp/successSave.jsp</result>
<result name="input">/jsp/personForm.jsp</result>
</action>
<action name="countries">
<result>/jsp/countries.jsp</result>
</action>
personForm.jsp:
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:form action="savePerson">
<s:textfield name="firstName" label="First Name" />
<s:textfield name="lastName" label="Last Name" />
<s:action name="countries" executeResult="true" />
<s:submit />
</s:form>
CountriesAction.java:
public class CountriesAction extends ActionSupport {
public String execute() {
countries = getCountries();
return SUCCESS;
}
private Map<String, String> getCountries() {
...
}
private Map<String, String> countries;
}
countries.jsp:
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:select name="countryId" label="Countries" list="countries"
headerKey="-1" headerValue="Please select the country ..."/>
SavePerson.action
public class SavePerson extends ActionSupport {
public void validate() {
if (firstName == "") {
addFieldError(firstName, "First Name is required.");
}
if (lastName == "") {
addFieldError(lastName, "Last Name is required.");
}
if (countryId == "-1") {
addFieldError(countryId, "Country is required.");
}
}
public String execute() {
//get the properties and save the person...
return SUCCESS;
}
private String firstName;
private String lastName;
private String countryId;
//corresponding setters and getters..
}
当我提交表单并发生验证错误时,例如,假设我们没有填写任何数据,因此输入字段“firstName”和“lastName”旁边将显示相应的消息。但国家/地区选择列表的情况并非如此,即使存在不会显示的操作错误。
我相信发生这种情况是因为父操作 SavePerson 是添加错误 (addFieldErrors) 的操作,但是当调用其他操作 Country(填充列表的操作)时,这些错误在该上下文中不可用,因为如果我在该 Action 中调用 hasErrors() ,它将为“false”,因此当呈现输入并检查是否存在任何错误以呈现消息时,将调用 hasErrors 并返回 false,因此不会呈现任何错误消息。
这种调用另一个操作来呈现另一个输入控件的方法是 Struts 2 FAQS 告诉我们的方法之一: http://struts.apache.org/2.2.1/docs/how-do-we-repopulate-controls-when-validation-fails.html
那么我怎样才能使这些操作上的控件呈现来自其父操作的操作错误。
有什么想法吗?
提前谢谢
最佳答案
我通过将调用者操作的错误引用设置为调用的操作来解决此问题。这是作为拦截器实现的:
public class CopyErrorsInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
ValueStack stack = invocation.getStack();
CompoundRoot root = stack.getRoot();
Action currentAction = (Action) invocation.getAction();
if (root.size() > 1 && isValidationAware(currentAction)) {
Action callerAction = getFirstActionBelow(root, currentAction);
if (callerAction != null && isValidationAware(callerAction)) {
ValidationAware currentActionVal = (ValidationAware) currentAction;
ValidationAware callerActionVal = (ValidationAware) callerAction;
//Copy the errors to the chained action.
currentActionVal.setActionErrors(callerActionVal.getActionErrors());
currentActionVal.setFieldErrors(callerActionVal.getFieldErrors());
}
}
return invocation.invoke();
}
/**
* Gets the first action below the passed action.
* @param root the stack to find the action
* @param current is the current action.
* @return
*/
private Action getFirstActionBelow(CompoundRoot root, Action current) {
boolean foundCurrentAction = false;
for(Object obj : root) {
if (obj == current) {
foundCurrentAction = true;
} else {
if (obj instanceof Action && foundCurrentAction) {
return (Action) obj;
}
}
}
return null;
}
private boolean isValidationAware(Action action) {
return action instanceof ValidationAware;
}
}
必须声明我自己的堆栈来扩展 struts-default:
<interceptors>
<interceptor name="copyErrors" class="com.afirme.casa.interceptor.CopyErrorsInterceptor"/>
<interceptor-stack name="defaultPlusErrors">
<interceptor-ref name="copyErrors"/>
<interceptor-ref name="defaultStack">
<param name="workflow.excludeMethods">
input,back,cancel,execute
</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
对于将被其他操作调用的操作(在本例中通过操作标签)必须引用这个新的拦截器堆栈。示例:
<action name="example" class="ExampleAction">
<interceptor-ref name="defaultPlusErrors"/>
<result>/jsp/example.jsp</result>
</action>
希望这有帮助,
阿尔弗雷多·奥
关于java - 支柱 2 s :action tag doesn't render action errors if any are present,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4045444/