如何在Struts 2

时间:2015-07-18 19:37:00

标签: java jsp struts2 ognl valuestack

我有一个搜索框,显示在每个页面上。搜索框的JSP代码通过切片插入到每个页面中。

搜索框有一个表单和一个操作类SearchAction,需要为下拉框预加载一些属性。 SearchAction类有一个input()方法,可以进行初始化。

有些页面在主要区域也有自己的形式。还有自己的动作类。他们还有一个input()方法可以进行一些预加载。

  1. 是否可以在同一视图中使用两个操作?
  2. 每个表单如何访问自己的操作属性。
  3. 如何在渲染JSP之前调用两个动作类的输入方法?
  4. 更新:

    我正在添加一个修剪过的示例,因为它可能不清楚我想要做什么。这是一个register.jsp的注册页面RegisterAction。该页面还包含搜索表单。 (顺便说一句:我省略了getter / setter以及动作类中的其他内容以保持简短)

    register.jsp:

    <s:form action="executeSearch">
        <s:textfield key="name" label="Name"/>
        <s:textfield key="age"  label="Age"/>
        <s:submit/>
    </s:form>
    
    <s:form action="executeRegister">
        <s:textfield key="firstName" label="First Name"/>
        <s:textfield key="lastName" label="Last Name"/>
        <s:textfield key="age" label="Age"/>
        <s:submit/>
    </s:form>
    

    struts.xml中:

    <action name="*Search" class="action.SearchAction" method="{1}">
        <result name="success">/searchresult.jsp</result>
    </action>
    
    <action name="*Register" class="action.RegisterAction" method="{1}">
        <result name="input">/register.jsp</result>
        <result name="success">/registerOk.jsp</result>
    </action>
    

    SearchAction.java:

    public class SearchAction extends ActionSupport {
    
        private String name;
        private int age;
    
        @Override
        public String input() throws Exception {
            // preload the search form with some demo data
            name = "test";
            age = 20;
            return INPUT;
        }
    
        @Override
        public String execute() throws Exception {
            return SUCCESS;
        }
    
        ...
    }
    

    RegisterAction.java:

    public class RegisterAction extends ActionSupport {
    
        private String firstName;
        private String lastName;
        private int age;
    
        @Override
        public String input() throws Exception {
            // preload the register form with some demo data
            firstName = "John";
            lastName = "Rambo";
            age = 10;
            return INPUT;
        }
    
        @Override
        public String execute() throws Exception {
            return SUCCESS;
        }
    
        ...
    }
    

    假设我称之为行动inputRegister.action。然后调用RegisterAction.input()。属性已设置。结果SUCCESS导致register.jsp被渲染。

    但是我的搜索表单呢。如何访问搜索操作及其模型。当然,这两者都不在ValueStack。我也没有看到调用SearchAction的任何方法来初始化它的模型的方法。我故意选择age作为两个动作类。在渲染页面中,您可以看到搜索表单还访问RegisterAction - 属性(因为它位于ValueStack之上)。但它需要访问SearchAction。它必须显示20而不是10。

    Rendered Jsp Page

    我显然做错了。但即使经过大量的谷歌搜索,我仍然没有找到正确的方法来做到这一点。

3 个答案:

答案 0 :(得分:1)

视图的概念用于执行任意数量的操作,任何操作都可以包含任意数量的结果。结果用于返回视图。返回视图的操作位于ValueStack之上,以便通过评估OGNL表达式轻松访问。结果视图可以映射到任何操作类中的任何操作。它对调用它的动作一无所知,但它可以再次使用OGNL来确定它。您可以将操作映射到同一操作类的不同方法,因此您不需要使用多种input()方法。

编辑:

你问题是你绑定的表格字段错了。每个表单都应该有一个单独的存储空间来正确显示它。字段以名称为界,您最好为搜索条件变量设置表单bean,并将其放在操作上下文中的某个位置。

<s:form action="executeSearch">
    <s:textfield key="searchBean.name" label="Name"/>
    <s:textfield key="searchbean.age"  label="Age"/>
    <s:submit/>
</s:form>

<s:form action="executeRegister">
    <s:textfield key="firstName" label="First Name"/>
    <s:textfield key="lastName" label="Last Name"/>
    <s:textfield key="age" label="Age"/>
    <s:submit/>
</s:form> 

注意:key属性会生成namelabelvalue

每个操作都需要初始化searchBean,除非它具有会话范围。如果将bean放入会话中,则应使用#session.前缀。有关OGNL的更多信息,请参阅文档页面。

答案 1 :(得分:1)

正如我发现的那样(请更正我):在向用户显示之前,需要在自己的操作中启动两种表单,当您要求注册表单时,搜索表单不会被启动,因为它的操作从未被调用。

这是一个常见问题,可以使用Ajax轻松处理,不要加载所有页面数据。请看http://struts.jgeppert.com/struts2-jquery-showcase/index.action。有一个主题选择选择框,已启动一次。加载页面的其他部分将通过Ajax完成,因此主题选择,启动选择框的操作,不需要重新运行。您可以轻松使用struts 2 jquery插件来实现它。

如果你不能使用Ajax(有任何理由),那就没有简单的方法了。您应该在EACH操作中手动启动搜索表单项,以确保您的struts标记可以读取搜索表单启动的数据。您可以根据需要考虑一下,在您的所有操作中剪切和粘贴搜索操作的主体!!

答案 2 :(得分:0)

确定。我正在回答我自己的问题。经过更多的Google时间,我发现在JSP中使用<s:action />初始化辅助操作可以满足我的需求。此标记还可以在变量中返回操作对象,我们可以在该变量上推送ValueStack表单。一个例子如下:

<!-- Initializes search model (preloading and stuff). -->
<s:action var="searchAction" name="inputSearch" >
    <s:param name="origin" value="inputRegister"/>
</s:action>

<!-- Pushing search action on ValueStack for the search form. -->
<s:push value="#searchAction">
    <s:form action="executeSearch">
        <s:hidden name="origin"/>
        <s:textfield key="name" label="Name"/>
        <s:textfield key="age"  label="Age"/>
        <s:submit/>
    </s:form>
</s:push>

<!-- This is the main form. It knows nothing about the search action. -->
<s:form action="executeRegister">
    <s:textfield key="firstName" label="First Name"/>
    <s:textfield key="lastName" label="Last Name"/>
    <s:textfield key="age" label="Age"/>
    <s:submit/>
</s:form>

这很好用。但是,有两个问题需要考虑:

  • 搜索操作用于许多页面。如果搜索表单的验证失败,我们需要找回原始页面。我通过一个&#34;起源&#34;解决了这个问题。参数。这被设置为主输入动作的名称。如果验证失败,搜索操作会链接到此操作。
  • 当JSP的呈现已经完全进行时,搜索操作很晚才被初始化。此时的例外可能会有问题。我必须小心翼翼地抓住所有的例外情况。