如果我有以下struts.xml配置:
<action name="input">
<result>/jsp/input.jsp</result>
</action>
<action name="result">
<result>/jsp/result.jsp</result>
<result name="input">/jsp/input.jsp</result>
</action>
一个只有一个字段的简单表单:
<s:form action="result">
<s:textfield name="firstName" label="First Name"/>
<s:submit/>
</s:form>
当验证失败时,让我们说每次提交动作(结果)时都会验证firstName长度是否超过3.当它失败时它会返回到输入页面,在这种情况下是input.jsp但是字段firstName已经填充(我刚刚提交的值不正确.Struts 2如何做到这一点?我想知道,因为据我所知,当我提交默认方法时,将输入数据POST到操作,那些与验证匹配的请求参数名称将是如果验证失败,它将返回到输入页面(作为POST的响应),只有那些请求参数可用。所以我想到的唯一想法是输入字段被这些请求参数填充但是,例如,如果我进行以下测试。假设我将使用以下内容模拟:
http://domain/myApp/input.action?firstName=alfredo 输入字段firstName将不会填充。
但是当结果来自验证时,它将被填充。我想知道Struts 2是否为了获取那些应该在请求参数上的值,推送请求参数对象(#parameters)并以这种方式填充它。
有人可以向我解释一下吗? Struts 2如何实现这种重新填充?
谢谢。
答案 0 :(得分:6)
我认为你误解了Struts2的一些概念和术语。你为什么称你的行为为“输入”和“结果”?这是不好的做法,并引入混淆 - 特别是因为“输入”是标准Struts2“结果”的名称。
应根据执行的操作调用操作。
基本模式很简单。 URL(http请求,GET或POST)对应于用户(浏览器,客户端)要求服务器(webapp,顶部带有struts2)执行某些操作。该操作可以提供多个结果,每个结果都会向用户返回一些信息(视图)(通常是通过JSP页面生成的HTML)。
一个简单的例子。让我们假设我想添加2个数字并显示结果。 (我从here回复了我的答案。
网址:http://...../addnumbers.action
此处操作的名称是“addnumbers” - 此请求将执行添加(不要被欺骗并认为它也会显示输入表单 - 它现在不 - 它只是正如其名称暗示的那样执行添加
典型的实施方式。在struts.xml中,您可以指定映射:
<action name="addnumbers" class="example.AddNumbersAction">
<result name="success">/AddNumbersResult.jsp</result> <!-- 'success' can be omitted here -->
</action>
您的Java行动:
public class AddNumbersAction extends ActionSupport {
private int x;
private int x;
private int z;
public String execute() {
z = x + y;
return SUCCESS;
}
// getters and setters ommited
}
您的AddNumbersResult.jsp
:
<div>
Result of addition:
<s:property value="x"> + <s:property value="y"> = <s:property value="z">
</div>
您可以(您应该!)检查输入网址http://.../mywebapp/addnumbers.action?x=10&y=20
是否按预期工作。
在幕后,Struts2(使用默认配置,默认的拦截器堆栈)正在创建AddNumbersAction
的实例,并通过反射调用与http参数对应的setter(尽最大努力进行类型转换 - 从这里的字符串到整数)。然后调用操作的默认方法(“execute”),结果为“success”,AddNumbersResult.jsp
用于生成html页面;在这个阶段,Action对象位于“值堆栈”(范围的种类)中,以便标签调用其getter。
一旦你清楚了这一点,仍然存在两个问题:如何显示用户输入数字的前一个html页面(“输入表单”),以及如何处理无效或不完整的参数。这些问题是相关的。
有几种(很少)方法。一种可能性:添加另一个动作映射:
<action name="addnumbersForm"> <!-- no action specified - will use ActionSupport -->
<result>/AddNumbersInputForm.jsp</result>
</action>
您的/AddNumbersInputForm.jsp
:
<div>
Please type two integer numbers to be added<p>
<s:actionerrors /> <!-- see below -->
<s:form action="addnumbers">
<s:textfield name="x" label="X value" />
<s:textfield name="y" label="Y value" />
<s:submit />
</s:form>
</div>
由于我们没有指定Action类,因此将使用虚拟默认值(并且将返回“success”)。有点“无为”的行动。
实际上,一个普通的html页面已经足够了,但是使用struts2标签我们获得了输入元素与action字段的“绑定”,因此我们可以处理错误和重试。通过(仅仅)约定,当参数不合适或无效时,Struts2动作将返回“输入”(而不是“成功”)(想法是动作说“你指示我执行此操作X但我不是成功,我需要你给我一个正确的输入,请 - 也许你想重试?“)。因此,在我们的示例中,我们为场景获取了完整的struts.xml映射:
<action name="addnumbersForm">
<result>/AddNumbersInputForm.jsp</result>
</action>
<action name="addnumbers" class="example.AddNumbersAction">
<result name="input">/AddNumbersInputForm.jsp</result>
<result name="success">/AddNumbersResult.jsp</result>
</action>
在我们的AddNumbersInputForm.jsp中,我们可以添加一个标签来显示验证错误(由Struts2内部或我们的代码生成)。
然后,如果我们按下带有无效参数的提交按钮,Struts将在其参数intercetor中检测到这一点(如果配置它则加上验证)并在调用execute()方法之前返回“input”。然后,将呈现AddNumbersInputForm.jsp
,但现在文本输入将使用先前的值重新填充。来自哪里?从操作,如果可以设置字段,或从请求本身。这个小小的魔法对于任何用户友好的html输入形式都是必不可少的(理解它是必不可少的)。
还有其他一些方法,但关键点在于区分:“用例”只是一个(添加两个数字),但操作是(概念上)两个:第一个只是向用户提供输入形式,第二个实际上是添加。这个概念应该反映在动作/网址的名称中。