Reputation: 4713
I am using xml based validation.
Problem:
I don't want validation to perform on input form when page loaded first time because all the fields are blank for user to fill in. Suppose for register form to add new student. It should perform once I click the button.
Note: I want to retain same url even when I do the validation on button click. New form URL is http://localhost:8000/Struts2_Spring_Crud/student/add
and if validation fail even than the url should be same.
struts.xml
<default-action-ref name="list"/>
<action name="list" class="com.myapp.actions.StudentAction" method="getAllStudents">
<!--<interceptor-ref name="myInterceptor"/>-->
<result name="success" type="tiles">/student.list.tiles</result>
</action>
<!--<action name="add">
<result type="tiles">/student.edit.tiles</result>
</action>-->
<action name="add" class="com.myapp.actions.StudentAction" method="insertOrUpdateStudent">
<result name="success" type="redirectAction">list</result>
<result name="input" type="tiles">/student.edit.tiles</result>
</action>
input form
<s:fielderror/>
<s:form action="add" method="POST">
<s:label name="name" value="Name *"/>
<s:textfield name="student.name" value="%{student.name}"/>
<s:fielderror fieldName="student.name"/>
<s:label name="age" value="Age *"/>
<s:textfield name="student.age" value="%{student.age}"/>
<s:submit name="saveForm" value="#title"/>
</s:form>
EDITED: If I am adding excludeMethods than this url http://localhost:8000/Struts2_Spring_Crud/student/add
is sending me to http://localhost:8000/Struts2_Spring_Crud/student/list
and my add form is not showing.
<action name="add" class="com.myapp.actions.StudentAction" method="insertOrUpdateStudent">
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<result name="success" type="redirectAction">list</result>
<result name="input" type="tiles">/student.edit.tiles</result>
</action>
Upvotes: 3
Views: 4672
Reputation: 21
I went through this problem and I finally found a work around for the case where you want only one action to handle everything and keep the same URL on the browser:
http://localhost:8000/Struts2_Spring_Crud/student/add
The struts.xml would only be:
<action name="add" class="com.myapp.actions.StudentAction" method="insertOrUpdateStudent">
<result name="success" type="redirectAction">list</result>
<result name="input" type="tiles">/student.edit.tiles</result>
</action>
The first time your page loads, the class associated to "add" action is first called. Then the field student from the class is null. Then you can rely on that fact to clear the validation that strut did.
So you should add a validate() method to your action class that will delete the validation errors that strut stupidly found:
public class StudentAction extends ActionSupport{
MyStudent student;
public MyStudent getStudent(){
return student;
}
public void setStudent(MyStudent student){
this.student=student;
}
public String execute(){
if (student==null) return INPUT; //First time page loads. We show page associated to INPUT result.
return SUCCESS; // If student is not null and execute was called it means that everything went fine, we should return SUCCESS and go to the page associated to the SUCCESS result.
}
public String insertOrUpdateStudent(){
if (student==null) return INPUT;
return SUCCESS;
}
.....
@Override
public void validate(){ //
if (student==null){ //First time page loads, student is null.
setFieldErrors(null); //We clear all the validation errors that strut stupidly found since there was not form submission.
}
}
}
Struts first validates the form by the xml validator stuff and then calls your validate method.
When you hit submit on the form, then strut creates a MyStudent object, call the setStudent(...) and then it goes field by field of the form calling the getStudent() and then calling the set"FieldName" of MyStudent object. After that, it validates the student object by the xml validator stuff and then calls your validate Method.
If after calling the validate() method there are still errors, then strut will return with an "INPUT" result without calling the execute() or the insertOrUpdateStudent() method in your case.
Hope this helps!!!
Upvotes: 2
Reputation: 24396
You can use fieldexpression validator
http://struts.apache.org/2.x/docs/fieldexpression-validator.html to do conditional validation, based on some hidden field like id
for example.
Upvotes: 0
Reputation: 10017
I always use aonther indicator to do this:
JSP:
<s:form action="add">
<s:hidden name="postBack" value="true"/>
<%-- your fields --%>
</s:form>
Action:
public String execute(){
if(!postBack){
return OPEN;
} else if(!validate()) {
return INPUT;
} else {
save();
return SUCCESS;
}
}
Configuration:
<action name="add" class="com.myapp.actions.StudentAction" method="insertOrUpdateStudent">
<result name="success" type="redirectAction">list</result>
<result name="input" type="tiles">/student.edit.tiles</result>
<result name="open" type="tiles">/student.edit.tiles</result>
</action>
Upvotes: 0
Reputation: 9528
I'm using annotation based validation. In my struts.xml I have
<interceptor-ref name="validation">
<param name="validateAnnotatedMethodOnly">true</param>
</interceptor-ref>
You might want to try adding excludeMethods for xml based validation
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
Here's the documentation for validation interceptor.
Upvotes: 0