Struts 2 验证和输入字段重新填充
如果我有以下 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 如何实现重新填充?
谢谢。
If I have the following struts.xml config:
<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>
And a simple form with only one field:
<s:form action="result">
<s:textfield name="firstName" label="First Name"/>
<s:submit/>
</s:form>
When validation fails, let's say that every time I submit the action (result) validates that firstName length is longer than 3. When it fails it will return to the input page, in this case input.jsp but with the field firstName already populated (with the incorrect value I just submitted. How does Struts 2 do this? I wonder because as I understand when I submit the default method is to POST the input data to the action and those request parameters names that match the validation will be validated. In case it fails the validation it will return to the input page (as a response of the POST) with only those request parameters available. So the only think that comes to my mind is that the input field gets populated with those request parameters but for example if I do the following test. Let's say I will simulate that with the following:
http://domain/myApp/input.action?firstName=alfredo
The input field firstName won't be populate.
But when the result comes from a validation it will be populated. I wonder if Struts 2 in order to get those values that should be on the request parameters, push the request parameter object (#parameters) and this way it gets populated.
Could someone explain that to me? How does Struts 2 achieve that repopulation?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您误解了 Struts2 的一些概念和术语。为什么您将您的操作称为“输入”和“结果”?这是不好的做法,并且会造成混乱——特别是因为“输入”是标准 Struts2“结果”的名称。
应根据操作执行的操作来调用操作。
基本模式很简单。 URL(http 请求、GET 或 POST)对应于用户(浏览器、客户端)请求服务器(Web 应用程序,顶部为 struts2)执行某些操作。该操作可以给出多个结果,每个结果都会向用户返回一些信息(视图)(通常是通过 JSP 页面生成的 HTML)。
一个简单的例子。假设我想添加 2 个数字并显示结果。 (我从 此处。URL
:
http://...../addnumbers.action
这里操作的名称是“addnumbers” - 此请求将执行加法(不要被欺骗并认为它还会显示输入表单 - 目前它不会显示 - 它只是执行加法,正如其名称所暗示的那样)
在 struts.xml 中指定一个典型的实现。 映射:
您的 Java 操作:
以及您的
AddNumbersResult.jsp
:您可以(您应该!)检查是否输入 url
http://.../ mywebapp/addnumbers.action?x=10&y=20
按预期工作,Struts2(使用默认配置、默认拦截器堆栈)正在创建
AddNumbersAction
的实例。并通过反射调用与http参数相对应的setter(尽最大努力进行类型转换 - 此处从字符串到整数)。然后调用action的默认方法(“execute”),结果为“成功”,并使用AddNumbersResult.jsp
生成html页面;在此阶段,Action 对象位于“值堆栈”(某种范围)中,以便标记调用其 getter。一旦你弄清楚了这一点,仍然存在两个问题:如何显示先前的 html 页面以供用户输入数字(“输入表单”),以及如何处理无效或不完整的参数。这些问题是相关的。
有几种(几种)方法。一种可能性:添加另一个操作映射:
以及您的
/AddNumbersInputForm.jsp
:由于我们没有指定 Action 类,因此将使用虚拟默认值(并且将返回“成功”)。有点像“什么都不做”的行为。
实际上,一个普通的 html 页面就足够了,但是使用 struts2 标签,我们获得了输入元素与操作字段的“绑定”,因此我们可以处理错误和重试。按照(纯粹)约定,当参数不充分或无效时,Struts2 操作将返回“输入”(而不是“成功”)(其想法是,该操作是在说“您指示我执行此操作 X,但我没有这样做”)成功了,我需要您给我一个正确的输入,请 - 也许您想重试?”)。因此,在我们的例子中,我们获得了该场景的完整 struts.xml 映射:
在我们的 AddNumbersInputForm.jsp 中,我们可以添加一个标签来显示验证错误(由内部的 Struts2 或由我们的代码生成)。
然后,如果我们按下带有无效参数的提交按钮,Struts 将在其参数拦截器中检测到这一点(如果您配置了它,则加上验证)并在调用execute() 方法之前返回“输入”。然后,将呈现
AddNumbersInputForm.jsp
,但现在文本输入将使用以前的值重新填充。从哪里?如果可以设置字段,则来自操作,或者来自请求本身。这个小魔法对于任何用户友好的 html 输入表单都是必不可少的(理解它也很重要)。还有其他一些方法,但要点是区分:“用例”在这里只是一个(添加两个数字),但操作(概念上)有两个:第一个只是向用户提供输入表单,第二个只是向用户提供一个输入表单。第二个实际上进行加法。这个概念应该反映在 actions/url 的名称中。
I think you are misunderstanding some Struts2 concepts and terms. Why are you calling your actions "input" and "result" ? That's bad practice, and introduce confusion -specially since "input" is the name of a standard Struts2 "result".
Actions should be called according to the action they perform.
The basic pattern is simple. A URL (http request, GET or POST) corresponds to the user (browser, client) asking the server (webapp, with struts2 in top) to perform some action. The action can give several results, each result will return some info (view) (typically a HTML generated via JSP page) to the user.
A simple example. Lets assume I want to add 2 numbers and display the result. (I recycle my answer from here.
URL :
http://...../addnumbers.action
Here the name of the action is "addnumbers" - this request will perform the addition (dont get tricked and think it will show also an input form - it will not, for now - it just performs the addition, as its name implies)
A typical implementation. In struts.xml you specify the mapping:
Your Java action:
And your
AddNumbersResult.jsp
:You can (you should!) check that typing the url
http://.../mywebapp/addnumbers.action?x=10&y=20
works as expected.Under the scenes, Struts2 (with the default configuration, default stack of interceptors) is creating an instance of
AddNumbersAction
and calling by reflection the setters corresponding to the http parameters (doing a best effort to make type conversions - from string to integer here). Then the default method of the action ("execute") is called, the result is "success", and theAddNumbersResult.jsp
is used to generate the html page ; in this stage, the Action object is in the "value Stack" (sort of scope) so that the tags invoke its getters.Once you get clear this, there remain two issues: how to display a previous html page for the user to enter the numbers (the "input form"), and how to deal with invalid or incomplete arguments. These issues are related.
There are several (few) approaches. One possiblity: add another action mapping:
And your
/AddNumbersInputForm.jsp
:As we do not specify a Action class, a dummy default will be used (and "success" will be returned). Kind of a "do nothing" action.
Actually, a plain html page would habe been enough here, but using the struts2 tags we attain a "binding" of the input elements with the action fields, and so we can deal with errors and retries. By (mere) convention, an Struts2 action will return "input" (instead of "success") when the arguments are unsufficient or invalid (the idea is that the action is saying "you instructed me to perfom this action X but I was not succesfull, I need that you give me a proper input, please - perhaps you want to retry?"). So, in our case we get this complete struts.xml mapping for the scenario:
And in our AddNumbersInputForm.jsp we can add a tag to show validation errors (generated by the Struts2 inside, or by our code).
Then, if we press the submit button with invalid arguments Struts will detect this in its parameter intercetor (plus validation if you configure it) and return "input" before calling the execute() method. Then, the
AddNumbersInputForm.jsp
will be rendered, but now the text inputs will be repopulated with the previous values. From where? From the action, if the field could be set, or from the request itself. This little magic is essential for any user-friendly html input form (and it's essential to understand it).There are some other ways, but the essential point is to distinguish: the "use case" is just one here (add two numbers), but the actions are (conceptually) two: the first just presents the user with a input form, the second actually does the addition. This concept should be reflected in the name of the actions/urls.