Struts1和ActionForm继承,数据混乱

发布于 2024-10-21 07:58:23 字数 5400 浏览 1 评论 0原文

我在使用 Struts1 ActionForm bean 时遇到问题。请查看我的 struts-config 的一部分:

<!-- RuleSearchForm is a sublass of RuleForm -->
    form-beans>
            <form-bean name="ruleForm" 
                type="forms.RuleForm">
            </form-bean>
            <form-bean name="ruleSearchForm" 
                type="forms.RuleSearchForm">
            </form-bean>
        </form-beans>
    <!-- Mappings -->
    <action path="/RuleList" 
            type="actions.RuleList"
            name="ruleSearchForm"
            scope="session"
            validate="false">
        <forward name="success" path="/html/view/RuleList.jsp"></forward>
    </action>
    <action path="/RuleCreate" 
            type="actions.RuleCreate" 
            name="ruleForm" 
            scope="request" 
            validate="false">
        <forward name="success" path="/html/view/CreateUpdateRule.jsp"></forward>
    </action>

以及我的 Actionform beans 代码的一部分:

public class RuleForm extends ActionForm {
    protected Integer   crid;       
    protected List levels;        
    /** Some other fileds go here */

    public Collection getLevels(){
        if(levels == null){
            levels = DAOClass.getLevels();
            Collections.reverse(levels);
        }
        return levels;
    }

    /** Other getters/setters go here */
}

public class RuleSearchForm extends RuleForm{

    /**
     * Avoid filter reset. If needs to be reset use {@link RuleForm#resetBeanFields()} directly.
     * */
    public void reset(ActionMapping mapping, HttpServletRequest request) {

    }

    /**
     * Add empty value. User should have an opportunity not to set value for this field.
     * */
    public Collection getLevels(){
        if(levels == null || levels.size() == 0){
            super.getLevels();
            levels.add(0, new Level());
        }
        return levels;
    }
}

问题是:

  1. 用户转到 /RuleList.do 并查看规则列表。 ruleSearchForm 用作将搜索参数传输到 /RulesList.do 操作的 bean。最初,这个 bean 是空的,只有 getLevels() 返回“空值”+从超类方法获取的级别列表。

  2. 用户转到/CreateRule.do,ruleForm用于收集用户输入。 levels 属性用于选择框。我得到了级别列表+空行。该空行不会添加到 RuleForm(名为ruleForm)中。它添加了 RuleForm 的子类。为什么没有静态字段、具有其他名称的超类 ActionForm bean 从它的子类实例中获取值???

  3. 如果用户保存规则并已重定向到/RuleList.do,他会看到填充(即填充)的搜索表单(“ruleSearchForm”),其中包含“ruleForm”中的值。

这是什么意思?请帮忙,我不明白 ActionForm Beans

UPD 之间的这些混乱的数据: 现在,我更改了 FormAction bean 的继承。我已经介绍了BaseFormBean。这个 BaseFormBean 有两个子元素:RuleForm 和 RuleSearchForm。 这没有帮助。尽管如此,一个 bean 的属性仍会转移到另一个 bean。

我的jsp代码: CreateUpdateRule.jsp:

<html:form action="/RuleSave.do">
<html:hidden property="crid"/>
<table border="0" cellpadding="2" cellspacing="0">
    <tr>
        <td><bean:message key="rule.levelId"/></td>
        <td><html:select property="levelId">
                <html:optionsCollection  property="levels" value="clid" label="name" />
            </html:select>
    </tr>
    <tr>
        <td><bean:message key="rule.timeStart"/></td>
        <td><html:text property="timeStartStr"/></td>
    </tr>   
    <tr>
        <td><bean:message key="rule.timeEnd"/></td>
        <td><html:text property="timeEndStr"/></td>
    </tr>   

    <tr>
        <td>
            <html:submit styleClass="wpsButtonText"><bean:message key="application.submit"/></html:submit>
        </td>
        <td>
            <input type="button" onclick="cancelOperation()" class="wpsButtonText" value="<bean:message key="application.cancel"/>" />
            <html:link styleClass="cancelLink" page="/RuleList.do"></html:link>
        </td>
    </tr>
</table
</html:form>

我的 RuleList.jsp:

<html:form action="/CritRuleList.do" >
<table style="width: 100%;">
    <tr>
        <td><bean:message key="rule.levelId"/></td>
        <td><html:select property=levelId">
                <html:optionsCollection  property="levels" value="clid" label="name" />
            </html:select>
        </td>
    </tr>
    <tr>    
        <td><bean:message key="rule.timeStart"/></td>
        <td><html:text property="timeStartStr" /></td>
    </tr>
    <tr>    
        <td><bean:message key="rule.timeEnd"/></td>
        <td><html:text property="timeEndStr" /></td>
    </tr>
    <tr>    
        <td colspan="2">
            <html:submit styleClass="wpsButtonText"><bean:message key="application.search"/></html:submit>
            <input type="button" onclick="cancelOperation(this)" class="wpsButtonText" value="<bean:message key="critrule.searchClear"/>" />
            <html:link styleClass="cancelLink" page="/RuleResetSearchFilter.do"></html:link>
        </td>   
    </tr>
</table>    
</html:form>

I have a problem using Struts1 ActionForm beans. Please, see a part of my struts-config:

<!-- RuleSearchForm is a sublass of RuleForm -->
    form-beans>
            <form-bean name="ruleForm" 
                type="forms.RuleForm">
            </form-bean>
            <form-bean name="ruleSearchForm" 
                type="forms.RuleSearchForm">
            </form-bean>
        </form-beans>
    <!-- Mappings -->
    <action path="/RuleList" 
            type="actions.RuleList"
            name="ruleSearchForm"
            scope="session"
            validate="false">
        <forward name="success" path="/html/view/RuleList.jsp"></forward>
    </action>
    <action path="/RuleCreate" 
            type="actions.RuleCreate" 
            name="ruleForm" 
            scope="request" 
            validate="false">
        <forward name="success" path="/html/view/CreateUpdateRule.jsp"></forward>
    </action>

And parts of my Actionform beans code:

public class RuleForm extends ActionForm {
    protected Integer   crid;       
    protected List levels;        
    /** Some other fileds go here */

    public Collection getLevels(){
        if(levels == null){
            levels = DAOClass.getLevels();
            Collections.reverse(levels);
        }
        return levels;
    }

    /** Other getters/setters go here */
}

public class RuleSearchForm extends RuleForm{

    /**
     * Avoid filter reset. If needs to be reset use {@link RuleForm#resetBeanFields()} directly.
     * */
    public void reset(ActionMapping mapping, HttpServletRequest request) {

    }

    /**
     * Add empty value. User should have an opportunity not to set value for this field.
     * */
    public Collection getLevels(){
        if(levels == null || levels.size() == 0){
            super.getLevels();
            levels.add(0, new Level());
        }
        return levels;
    }
}

The problem is:

  1. User goes to /RuleList.do and sees the list of rules. ruleSearchForm used as a bean for transferring search params to /RulesList.do action. Initially tihs bean is empty, only getLevels() returns "empty value" + list of levels got from superclass method.

  2. User goes to /CreateRule.do, ruleForm is used for collecting user input. levels property is used in selectbox. And I get there list of levels + empty row. This empty row is not added in RuleForm (named ruleForm). It's added it subclass of RuleForm. Why does super class ActionForm bean with NO static fields, with other name gets values from it's sublass instance???

  3. If users saves Rule and has been redirected to /RuleList.do, the he sees populated (i.e. filled) search form ("ruleSearchForm") with values from "ruleForm".

What does it mean? Please help, I don't understand this mess of data beetween ActionForm Beans

UPD:
Now, I've changed inheritance of FormAction beans. I've introduced BaseFormBean. This BaseFormBean got two children: RuleForm and RuleSearchForm.
It didn't help. Still attributes from one bean are moved to another.

My jsp code:
CreateUpdateRule.jsp:

<html:form action="/RuleSave.do">
<html:hidden property="crid"/>
<table border="0" cellpadding="2" cellspacing="0">
    <tr>
        <td><bean:message key="rule.levelId"/></td>
        <td><html:select property="levelId">
                <html:optionsCollection  property="levels" value="clid" label="name" />
            </html:select>
    </tr>
    <tr>
        <td><bean:message key="rule.timeStart"/></td>
        <td><html:text property="timeStartStr"/></td>
    </tr>   
    <tr>
        <td><bean:message key="rule.timeEnd"/></td>
        <td><html:text property="timeEndStr"/></td>
    </tr>   

    <tr>
        <td>
            <html:submit styleClass="wpsButtonText"><bean:message key="application.submit"/></html:submit>
        </td>
        <td>
            <input type="button" onclick="cancelOperation()" class="wpsButtonText" value="<bean:message key="application.cancel"/>" />
            <html:link styleClass="cancelLink" page="/RuleList.do"></html:link>
        </td>
    </tr>
</table
</html:form>

my RuleList.jsp:

<html:form action="/CritRuleList.do" >
<table style="width: 100%;">
    <tr>
        <td><bean:message key="rule.levelId"/></td>
        <td><html:select property=levelId">
                <html:optionsCollection  property="levels" value="clid" label="name" />
            </html:select>
        </td>
    </tr>
    <tr>    
        <td><bean:message key="rule.timeStart"/></td>
        <td><html:text property="timeStartStr" /></td>
    </tr>
    <tr>    
        <td><bean:message key="rule.timeEnd"/></td>
        <td><html:text property="timeEndStr" /></td>
    </tr>
    <tr>    
        <td colspan="2">
            <html:submit styleClass="wpsButtonText"><bean:message key="application.search"/></html:submit>
            <input type="button" onclick="cancelOperation(this)" class="wpsButtonText" value="<bean:message key="critrule.searchClear"/>" />
            <html:link styleClass="cancelLink" page="/RuleResetSearchFilter.do"></html:link>
        </td>   
    </tr>
</table>    
</html:form>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

む无字情书 2024-10-28 07:58:23

在您描述的情况下调用子类方法听起来很奇怪。要找出发生这种情况的原因,您需要调试代码 - 在 RuleSearchForm.getLevels() 方法的 if 构造中放置一个断点,并查看它是否真的被调用(以及调用源自何处)从)。

除此之外,您可以尝试将级别的填充逻辑完全移出表单,而是在操作中进行。因此,在 RuleCreate 操作中,您将执行以下操作:

List levels = DAOClass.getLevels();
Collections.reverse(levels);
request.setAttribute("levels", levels);

It sounds very strange that a subclass method would be called in the case you've described. To find out why it's happening, you need to debug your code - put a breakpoint inside the if construct of the RuleSearchForm.getLevels() method and see if it is really called (and where did the call originate from).

Other than that, you could try to move the populating logic of levels away from the form(s) altogether, and instead do it in the action. So, in the RuleCreate action you would do something like this:

List levels = DAOClass.getLevels();
Collections.reverse(levels);
request.setAttribute("levels", levels);
玩物 2024-10-28 07:58:23

这段代码确实很难理解,而且您仍然遗漏或更改了一些映射(RuleCreate 或 CreateRule)。我的猜测是您误解了使用哪种表单声明来填充字段和选项集合。当您创建这样的表单时,

<html:form action="/RuleSave.do">

选择框的值取自与 struts-config 中的 RuleSave 操作关联的表单 bean,而不是从转发到此 jsp 的操作的表单中获取。

来自 http://struts.apache.org/1.2.x/ userGuide/struts-html.html#form

呈现 HTML 元素...根据关联 ActionMapping 的表单 Bean 规范,定位并创建表单 Bean(如有必要)。

This code is really hard to follow, and you still left out or changed some mappings (RuleCreate or CreateRule). My guess would be that you have a misunderstanding in which form declaration is used to populate the fields and the options collection. When you create a form like this

<html:form action="/RuleSave.do">

The values for the select box are taken from the form bean associated with the RuleSave action in your struts-config, not from the form of the action that forwarded to this jsp.

From http://struts.apache.org/1.2.x/userGuide/struts-html.html#form:

Renders an HTML element ... The form bean is located, and created if necessary, based on the form bean specification for the associated ActionMapping.

庆幸我还是我 2024-10-28 07:58:23

[问题已解决。
1. 正如 Tommi 所说,我检查了 DAO 代码。 DAO 返回保存在静态私有字段中的 bean 列表。

/**
     * Add empty value. User should have an opportunity not to set value for this field.
     * */
    public Collection getLevels(){
        if(levels == null || levels.size() == 0){
            super.getLevels();
            levels.add(0, new Level());
        }
        return levels;
    }

因此,每次添加空 bean 时,我都会更改对象的静态列表。可怕的错误。

  1. 参数传输。我已经为WebSphere Portal 创建了struts1 应用程序。 Portal 没有重定向,因为我使用 portlet,而不是页面。这就是为什么请求参数存在于请求中,而没有渲染最后一个jsp页面。也已经解决了。

The [roblem has been resolved.
1. As Tommi said, I've inspected DAO code. DAO returns list of beans kept in static private field.

/**
     * Add empty value. User should have an opportunity not to set value for this field.
     * */
    public Collection getLevels(){
        if(levels == null || levels.size() == 0){
            super.getLevels();
            levels.add(0, new Level());
        }
        return levels;
    }

So each time I add empty bean I do change that static list of objects. Terrible bug.

  1. Params transferring. I've created struts1 app for WebSphere Portal. Portal doesn't have redirect, because I work with portlets, not with pages. That is why request parameters live in request unlit last jsp page is rendered. It has been also solved.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文