我有一个搜索框,显示在每个页面上。搜索框的JSP代码通过切片插入到每个页面中。
搜索框有一个表单和一个操作类SearchAction
,需要为下拉框预加载一些属性。 SearchAction
类有一个input()
方法,可以进行初始化。
有些页面在主要区域也有自己的形式。还有自己的动作类。他们还有一个input()
方法可以进行一些预加载。
更新:
我正在添加一个修剪过的示例,因为它可能不清楚我想要做什么。这是一个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。
我显然做错了。但即使经过大量的谷歌搜索,我仍然没有找到正确的方法来做到这一点。
答案 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
属性会生成name
,label
和value
。
每个操作都需要初始化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>
这很好用。但是,有两个问题需要考虑: