java - Struts 2 验证和输入字段重新填充

标签 java model-view-controller validation struts2

如果我有以下 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 如何实现重新填充?

谢谢你。

最佳答案

我认为您误解了一些 Struts2 概念和术语。你为什么称你的行为为“输入”和“结果”?这是不好的做法,并且会引起混淆——特别是因为“输入”是标准 Struts2“结果”的名称。

应根据 调用操作行动 他们表演。

基本模式很简单。 URL(http 请求、GET 或 POST)对应于用户(浏览器、客户端)向服务器(webapp,顶部带有 struts2)请求 执行一些操作 . Action 可以给几个结果 ,每个结果都会向用户返回一些信息( View )(通常是通过 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 (尽最大努力进行类型转换 - 此处从字符串到整数)。然后调用 Action 的默认方法(“execute”),结果为“success”,AddNumbersResult.jsp用于生成html页面;在这个阶段,Action 对象位于“值栈”(某种范围)中,以便标签调用它的 getter。

一旦你明白了这一点,还有两个问题:如何显示以前的 html 页面供用户输入数字(“输入表单”),以及如何处理无效或不完整的参数。这些问题是相关的。

有几种(少数)方法。一种可能性:添加另一个 Action 映射:
   <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 类,因此将使用虚拟默认值(并且将返回“成功”)。一种“什么都不做”的 Action 。

实际上,一个普通的 html 页面在这里就足够了,但是使用 struts2 标记我们实现了输入元素与操作字段的“绑定(bind)”,因此我们可以处理错误和重试。按照(仅)约定,当参数不足或无效时,Struts2 Action 将返回“输入”(而不是“成功”)(这个想法是 Action 说“你指示我执行这个 Action 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 将在其参数拦截器中检测到这一点(如果您配置它,则加上验证)并在调用 execute() 方法之前返回“输入”。然后,AddNumbersInputForm.jsp将被渲染,但现在文本输入将重新填充以前的值。从哪里?来自操作,如果可以设置字段,或者来自请求本身。这个小魔法对于任何用户友好的 html 输入表单都是必不可少的(理解它是必不可少的)。

还有其他一些方法,但关键是要区分:“用例”在这里只是一个(添加两个数字),但 Action (概念上)是两个:第一个只是向用户提供输入表单,第二个实际上是加法。这个概念应该反射(reflect)在操作/网址的名称中。

关于java - Struts 2 验证和输入字段重新填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3873460/

相关文章:

wpf - ValidationRules 没有绑定(bind)

java - 如何将一个函数的验证包装在另一个函数中?

java - 将项目 JRE 构建路径条目设置为 'JavaSE-1.7'

java - 在没有 GAE 和 Apache Commons 的情况下在 GWT 中上传文件

java - JSF中MVC的矛盾解释

c++ - 使用 QStyledItemDelegate::paint() 直接在 QListView 上绘制小部件

java - 从 Java 调用 MATLAB 命令窗口时如何隐藏它?

java - LinkedHashmap 和 LinkedTreemap 的区别

php - Laravel - 如何将变量传递给布局局部 View

objective-c - iOS 中 UITextField 中的密码验证