5

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

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

有些页面在主区域也有自己的表单。也有自己的动作课。他们还有一种input()方法可以进行一些预加载。

  1. 是否可以在同一个视图中使用两个操作?
  2. 每个表单如何访问它自己的操作属性。
  3. 在呈现 JSP 之前,我怎么能设法让两个动作类的输入法都被调用呢?

更新:

我正在添加一个精简的示例,因为可能不清楚我要做什么。这是一个注册页面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;
    }
    
    ...
}

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

但是我的搜索表单呢?如何访问搜索操作及其模型。当然,这些都不是ValueStack。而且我也没有看到调用任何方法SearchAction来初始化它的模型的方法。我故意选择age参加这两个动作课程。在呈现的页面中,您可以看到搜索表单也访问RegisterAction-*.properties(因为它位于 顶部ValueStack)。但它需要访问SearchAction. 它必须显示 20 而不是 10。

渲染的 Jsp 页面

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

4

3 回答 3

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的更多信息。

于 2015-07-18T21:09:42.433 回答
1

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

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

如果您不能使用 Ajax(出于任何原因),那么没有简单的方法。您应该在每个操作中手动启动搜索表单项,以确保您的 struts 标签可以读取搜索表单启动的数据。您可以根据需要考虑如何在所有操作中剪切和粘贴搜索操作的主体!

于 2015-07-19T08:55:26.960 回答
0

好的。我正在回答我自己的问题。经过更多的 Google 时间后,我发现<s:action />在 JSP 中初始化辅助操作可以满足我的需要。这个标签还可以在一个变量中返回动作对象,我们可以将其推送到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>

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

  • 搜索操作用于许多页面。如果搜索表单的验证失败,我们需要找回原来的页面。我通过使用“原点”参数解决了这个问题。这设置为主要输入操作的名称。如果验证失败,则搜索操作链接到此操作。
  • 当 JSP 的呈现已经在完全进行中时,搜索操作被初始化得很晚。此时的异常可能是有问题的。我必须自己小心捕捉所有异常。
于 2015-07-21T11:32:17.877 回答