【问题标题】:Struts2 Repopulate form information when validation failsStruts2 验证失败时重新填充表单信息
【发布时间】:2013-07-22 14:20:22
【问题描述】:

我有一个页面,其中的表单预先填充了用户信息。这是一个用户资料页面。我对某些字段进行了验证,但目前我的验证方法只是硬编码以执行addFieldError("exp", "Cats");,其中exp 是正在验证的变量,Cats 是随机消息。该表单具有选择和双重选择,我通过在 jsp 中执行操作来重新填充它们。 (见下文)

这是整个表格:

<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>

下拉列表填充正常。问题是我认为将保存在值堆栈中并在重新加载 jsp 时保留的值(%{formAction}%{profile.email} 等)在我重新加载 jsp 时没有保留。如何在验证失败后重新加载页面时捕获这些值并呈现它们?我已经尝试将它们添加到会话中,但这往往会变得混乱,我不确定如何让它与 formAction 一起使用。

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>

加载表单的 Action 中的代码 sn-p:

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;

}

来自更新用户配置文件的 Action 的代码 sn-p:

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";
}

更新

问题几乎就是coding_idiot所说的。在加载表单的操作中,我需要获取信息以最初填充表单(有这个)。在更新信息的操作中,我需要将信息设置器放入表单中,如果在验证失败后应该重新填充表单,我需要一个获取器来获取新信息的位置。我通过使用从表单获得的数据填充更新操作中的validate() 函数中的profile 对象,然后为profile 对象提供设置器来解决此问题。我不必对我的 .jsp 进行任何更改

【问题讨论】:

  • 它们应该被保留;您是否使用chainredirectAction 为您input 结果? Action 中有 profile 对象的 getter 和 setter 吗?
  • 我没有使用chainredirectAction。我确实有 profile 对象的 getter 和 setter。

标签: java validation struts2 field repopulation


【解决方案1】:

我不知道您在操作中写了什么,但从上面我可以推断这是对功能问题的轻微误解。您有带有名称的字段 - 电子邮件、whenAvailable 等,但它们的值是从配置文件对象中获取的。

你怎么能指望用不存在的东西来设置它?

To make it more clear : 
Values that go from JSP to action is email, but what comes back is profile.email, instead it 
should have been just email, or you can simply skip the value attribute or you can change your 
field-name to profile.email

如果有帮助,请告诉我。

[编辑]

再次阅读您的问题,配置文件的获取器和设置器将无济于事,因为什么 正在执行的操作只是原始字段(电子邮件等),因此您应该为这些字段设置 getter/setter,然后将这些字段重新填充到 JSP 中 您可以简单地用于例如:

 <s:textfield name="whenAvailable" value="%{whenAvailable}" />

 <s:textfield name="whenAvailable"/>

【讨论】:

  • 嗨coding_idiot。这可能是个问题。我还没试过,但是formAction 设置不正确是怎么回事?
  • 因为 formAction 永远不会作为请求参数提交!您可以简单地创建一个隐藏字段来提交 formAction,然后当它返回时,它将被自动填充。
  • 我添加了&lt;s:hidden name="formAction" value="%{formAction}" /&gt; 只是为了得到相同的结果。加载的jsp中的表单显示&lt;form id="" action="" method="post" enctype="multipart/form-data"&gt;
  • 您需要先设置formAction,这样它才能在JSP 中正常运行,然后它会因为隐藏字段而返回。这个隐藏字段之前 formAction 的值是多少。
  • 它最初设置正确,因为如果它验证正确,我可以更新。在这个例子中,它是&lt;form id="updateProfile" name="updateProfile" action="/TeamBuilder/updateProfile.action" method="post" enctype="multipart/form-data"&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 2010-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
相关资源
最近更新 更多