I have a page with a form that is prepopulated with user information. It is a user profile page. I have validation for some of the fields in place but currently my validation method is just hard coded to execute addFieldError("exp", "Cats");
where exp
is a variable that is being validated and Cats is a random message. The form has selects and a doubleselect which I am repopulating by executing actions in the jsp. (Seen Below)
This is the entire form:
<s:form action="%{formAction}" method="post" enctype="multipart/form-data">
<div id="buttons">
<s:submit value="Save" />
</div>
<div id="left_column" class="divStyle">
<div id="picture">
<div id="picture_border">
Picture should go here 150px x 150px
</div>
<s:file name="upload" label="File" />
</div>
<hr />
<div id="contact" class="divPad">
<h3>Contact Information</h3>
<s:textfield name="email" value="%{profile.email}" required="true" />
</div>
<hr />
<div id="availabilityDuration" class="divPad">
<h3>When Available</h3>
<s:textfield name="whenAvailable" value="%{profile.whenAvailable}" />
<h3>Availability Length</h3>
<s:textfield name="availabilityLength" value="%{profile.availabilityLength}" />
<h3>Desired Credit</h3>
<s:action name="CreditSelectAction" executeResult="true" />
</div>
</div>
<div id="right_column" class="divStyle">
<div id="basic_info" class="divPad">
<h4>College & Major</h4>
<s:action name="CollegeMajorsSelectAction" executeResult="true" />
<hr />
<h4>Years of Work Experience</h4>
<s:action name="ExpYearsSelectAction" executeResult="true" /> <hr />
<h4>Undergrad</h4>
<s:action name="UndergradSelectAction" executeResult="true" /> <hr />
<h4>Graduation Year</h4>
<s:action name="GradYearSelectAction" executeResult="true" />
</div>
<hr />
<div id="aboutDescription" class="divPad">
<h3>About Me</h3>
<s:textarea name="comments" value="%{profile.comments}" cols="40" rows="10" />
</div>
<hr />
<div id="skillsNeeds" class="divPad">
<h3>Skills</h3>
<div id="userSkillList">
<s:iterator value="profile.skills" status="status">
<div>
<h5 class="formLabels">Skill Description</h5>
<s:textfield name="userSkillDescription_%{#status.count}" value="%{description}" />
<h5 class="formLabels">Years of Experience</h5>
<s:textfield name="userSkillExperience_%{#status.count}" value="%{experience}"/>
<h5 class="removeSkillLink" onclick="removeUserSkill(this);">Remove Skill</h5>
</div>
</s:iterator>
<h5 class="addSkillLink" id="addSkill" onclick="addUserSkill();">Add New Skill</h5>
</div>
</div>
</div>
</s:form>
The dropdowns are populating alright. The problem is that the values that I thought would be saved in the value stack and retained upon reloading the jsp (%{formAction}
, %{profile.email}
, etc.) are not being retained when I reload the jsp. How do I capture these values and present them when the page is reloaded after the failed validation? I have tried adding them to the session, but that tends to get messy and I'm not sure how to get that to work with the formAction
.
Code from struts.xml:
<action name="updateProfile" class="profiles.actions.UpdateProfileAction" method="execute">
<!-- <interceptor-ref name="basicStack"/>
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/jpeg,image/gif,image/png,image/jpg</param>
</interceptor-ref>
<interceptor-ref name="validation"/>
<interceptor-ref name="workflow"/> -->
<result name="success">/index.jsp</result>
<result name="input">/jsp/editProfile.jsp</result>
</action>
Code snippet from the Action that loads the form:
public String execute()
{
// get the user profile
String result = "success";
//If the profile is null, then the user is new and does not yet have a profile
//NOTE: If the user's profile doesn't exist, when trying to view someone else's
//profile, they will be redirected to edit their own.
if(user.intValue() == 0)
{
logger.info("New User Detected. Returning Failure.");
result = "failure";
}
else
{
//If the userid is null, we are loading the user's profile
//Otherwise, we are viewing someone else's profile
if(userid == null)
userid = user.toString();
profile = dao.selectCurUserById(Integer.parseInt(userid));
// get all of my projects
this.setMyProjects(projectDAO.selectMyProjects(Integer.parseInt(userid)));
// get all of the projects i've been invited to
this.setJoinedProjects(projectDAO.selectJoinedProjects(Integer.parseInt(userid)));
}
return result;
}
Code snippet from that Action that updates the user profile:
public String execute()
{
// request that sent from the client
HttpServletRequest request = ServletActionContext.getRequest();
Map<String, Object> session = ActionContext.getContext().getSession();
profile = new UserProfile();
id = ((authentication.beans.User) session.get("currentUser")).getId();
profile.setId(id);
profile.setEmail(email);
profile.setAvailabilityLength(availabilityLength);
profile.setComments(comments);
profile.setUndergrad(Integer.parseInt(undergrad));
profile.setWhenAvailable(whenAvailable);
profile.setYear(year);
profile.setCredit(credit);
profile.setMajor(Major.getMajor(major));
profile.setCollege(College.getCollege(college));
profile.setExp(exp);
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy");
profile.setModify(sdf.format(new GregorianCalendar().getTime()));
//If file is not null, then the user is uploading an image for his/her
//profile
if(file != null)
{
byte[] b = new byte[(int) file.length()];
try
{
new FileInputStream(file).read(b);
b = Base64.encode(b);
}
catch (IOException e)
{
// TODO Auto-generated catch block
profile.setComments(profile.getComments() + "\n" + e.getMessage());
}
profile.setPic(b);
}
// get all of the params and then process the user skills
HashMap<String,String[]> params = (HashMap<String,String[]>)request.getParameterMap();
// process the user skills
profile.setSkills(processSkills(params));
// add the userid to the skills
for(int i = 0; i < profile.getSkills().size(); i++){
profile.getSkills().get(i).setUserID(profile.getId());
}
//TODO: Check the result and do error handling
boolean result = dao.updateProfile(profile);
return "success";
}
UPDATE
The problem was pretty much what coding_idiot said. In the action for loading the form, I needed to have getters for the information to initially populate the form (had this). In the action for updating the information, I needed to have setters for the information put into the form AND a getter for where to get the new information if the form should be repopulated after a failed validation. I fixed this by populating the profile
object in the validate()
function in the update action with the data I got from the form and then providing a setter for the profile
object. I did not have to make any changes to my .jsp