结构化的表单提交

为什么?

HTML表单提交的数据模型是一个映射-每个表单字段都有一个名称,提交时,服务器按名称检索值。

一是缺少结构;如果表单中有一个重复的结构,而该结构又包含一个嵌套的重复结构,那么仅仅给它一个名称就无法区分嵌套结构。瞧,你说不出来(A, B), (C, D)从…起(A, B, C), (D)因为这个地图只给你一个4项的列表。一个类似的相关问题是,当您将复选框放在表单的重复部分时。如果其中一些被检查,而另一些没有,服务器将永远无法确定哪些被检查,因为当表单提交时,这些信息将丢失。

另一个问题是名称的范围。在HTML中,所有表单字段都需要有唯一的名称。这类似于在编程语言中将所有变量都设置为全局变量,而在像Jenkins这样的模块化可扩展系统中,这是不可取的。必威国际有限公司名称的范围还防止表单的一部分在同一表单的其他地方被重用。

为了避免这些问题并进一步简化服务器端,在Jenkins中引入了“结构化表单提交”的概念。必威国际有限公司

什么是结构化表单提交?

结构化表单提交是指数据模型是JSON对象树而不是映射的表单提交。这是通过让客户端在表单提交时计算JSON表示,并将其作为一个隐藏文本字段(连同所有其他字段)发送给服务器来实现的。

结构是由几个因素决定的。首先,表单字段的名称成为JSON属性名称。出于兼容性原因,名称可以有任何“abc.def.”类型的前缀,前缀部分将被忽略。例如,在最简单的情况下,下面的表单将在右侧生成JSON结果。

< >形式<输入类型文本的名字my.name/><输入类型复选框的名字我的选择/>给我发电子邮件
的名字Kohsuke选项符合事实的

任何中间标记都可以具有'name'属性,它将后代标记分组为中间对象。考虑下面的例子:

< >形式< div的名字第一><输入类型文本的名字my.name/><输入类型复选框的名字我的选择/>给我发电子邮件< / div >< div的名字第二><输入类型文本的名字my.name/><输入类型复选框的名字我的选择/>给我发电子邮件< / div >...
<输入类型密码的名字my.password/>< / div >
第一:{的名字Kohsuke选项符合事实的},第二:{的名字杰西选项},密码秘密

如果有多个元素具有相同的名称,则将它们的值聚合到一个数组中。考虑下面的例子:

< >形式< div的名字><输入类型文本的名字my.name/><输入类型复选框的名字我的选择/>给我发电子邮件< / div >< div的名字><输入类型文本的名字my.name/><输入类型复选框的名字我的选择/>给我发电子邮件< / div >...
<输入类型密码的名字my.password/>< / div >
: [{的名字Kohsuke选项符合事实的}, {的名字杰西选项} ],密码秘密

嵌套的深度可以是任意的。

文件上传

在结构化表单中上传的文件被重命名为唯一名称,JSON树将拥有这个唯一表单名称的名称。为了保持向后兼容,此处理要求文件INPUT元素包含jsonAware="yes"属性:

< >形式< div的名字><输入类型文本的名字my.name/><输入类型文件的名字我的钥匙jsonAware是的/>< / div >< div的名字><输入类型文本的名字my.name/><输入类型文件的名字我的钥匙jsonAware是的/>< / div >
: [{的名字Kohsuke关键随机数字1234567}, {的名字杰西关键randomIdabcdefg} ] }
staplerRequest.getFileItem(随机数字1234567)回来该文件已上载Kohsuke和staplerRequest.getFileItem (randomIdabcdefg)回来该文件已上载杰西。

高级的主题

有时,标记和表单的布局使得分组表单字段不可能有一个共同的祖先元素(例如,分组表单元素通常分布在多个表行中)。在这种情况下,你可以把nameref属性将多个元素树合并为一个。这个机制主要是在Jenkins表单布局标签中使用的,所以插件开发者不需要担必威国际有限公司心这个问题。考虑下面的例子:

< >形式<表>的名字cvsid美国广播公司>< td ><输入类型文本的名字CVSROOT/>< / td >< / tr >nameref美国广播公司>< td ><输入类型文本的名字模块/>< / td >< / tr >的名字svniddef>< td ><输入类型文本的名字统一资源定位地址/>< / td >< / tr >namerefdef>< td ><输入类型文本的名字模块/>< / td >< / tr >
cvs:{CVSROOT...模块...},svn:{统一资源定位地址...模块...} }

如果nameref属性指向复选框或单选按钮INPUT元素,只有在选择/选中INPUT元素时才提交从属结构。当这样的INPUT元素用于控制嵌套表单部件的可见性时,这是很方便的。

编写服务器代码

您可以通过调用StructuredForm.get(请求),但通常只有在您负责整个表单提交时才需要这些代码。Descriptor.configure ()Descriptor.newInstance ()使用JSONObject,它对应于您通过它贡献的表单片段config.jelly/global.jelly

以Jenkins核心中的描述符实现为例。必威国际有限公司

数据绑定

StaplerRequest从JSONObject提供了几种数据绑定方法,这大大简化了表单数据的对象实例化。请参阅StaplerRequest.bindJSONXXX方法的细节。

通常,如果使用标准数据绑定约定

您可以重写您的配置方法GlobalConfiguration一次绑定所有字段并保存它。

@Override平民的布尔值配置(StaplerRequest req, JSONObject json) {req. bindjson (,json);save();回来符合事实的; }

或者,您可以在您拥有的每个setter中调用save方法:

@DataBoundSetter平民的无效的setCredentialID (字符串credentialID) {.credentialID = credentialID;save ();}