emmanuel字体书写

在上一篇有关Bean验证框架早期草案的文章之后,InfoQ与Emmanuel Bernard坐下来,以了解有关该提案的更多信息以及专家组正在寻求的社区参与。

InfoQ :我期望规范会支持某种XML模型以及注释,但是似乎不支持。 这是您离开的东西吗?

Emmanuel Bernard(EB) :该规范将支持XML模型。 但是,我们希望在处理XML描述符之前先确定功能集和元模型。 注释可以用作JSR 303 Bean验证实现中的内部模型。 一旦我们正确定义了注释模型,XML应该接近换位,只是另一种语言。

InfoQ :您是否打算支持错误消息的层次结构-因此,我有一种显示一般错误消息的标准方法,如果需要,可以用页面/屏幕特定的错误消息覆盖该错误消息?

EB :我不确定我是否理解您的问题,但让我尝试从两个角度回答
a)Bean Validation规范使您可以通过基于经典文件系统的ResourceBundle本地化来对约束错误消息进行外部化和国际化。 约束可以声明键,而不是使用“硬编码”消息。

@Length(max = 50, message="{constraint.name.tooLong}")
String name;

## French resourceBundle constraint.name.tooLong =
@Length(max = 50, message="{constraint.name.tooLong}")
String name;

## French resourceBundle constraint.name.tooLong =
。name.tooLong=最高人数{max}

为了超越此模型并提供与应用程序或表示框架(例如Web框架)的自然集成,消息解析策略是完全可插入的。

让我们举个例子:Web Beans提倡上下文组件的概念(例如事件,页面,请求,对话,业务流程)。 Web Bean可以使用Bean验证并插入其上下文感知的消息解析策略:包含上下文表达式的错误消息将被解析。

另一个例子。 Wicket资源束解析是分层定义的。 它首先尝试在面板资源文件中找到键,然后在页面资源文件中找到键,最后在应用程序资源文件中找到键。 Wicket可以按照这种模式提供自己的消息解析实现。

在这两种情况下,上下文信息对于提供合适的错误消息都是至关重要的。 Bean Validation调用者更容易了解此上下文:通过提供自定义消息解析实现,它为用户提供自然而同质的体验,同时仍将验证工作委托给Bean Validation。

b)从哲学上讲,我想知道为什么您需要在特定页面上更改约束消息? 通常,约束消息需要在特定上下文中“自定义”,因为看起来是一个约束的确是在不同上下文中应用的两个不同约束。 Bean验证规范提供了一种描述上下文约束的机制。 每个约束都属于一个或多个组。 验证对象时,可以提供一个组列表来选择应用验证的上下文。 我在博客条目中描述了一些组的用例。

InfoQ :国际化和验证的一个常见问题是验证规则可能在区域设置之间有所不同。 例如,字母数字测试可能会有所不同。 如何处理?

EB :我通常看到的是约束规则更多地取决于属性值,而不是实际的语言环境。 以地址的典型示例为例,邮政编码或电话号码限制取决于该地址所属的国家/地区。

有些约束不会改变(不是null,数据库中的最大长度),但是有些约束会因国家/地区而异。 今天,该规范通过提供类级别约束来解决此问题。 类级别的约束可以访问Bean实例而不是其属性之一,并且可以基于多个属性应用约束逻辑。 电话号码验证逻辑将对法国和美国应用不同的规则,甚至可能基于现有数据库而不是格式规则为加拿大电话号码调用外部服务。

这是一个有趣的问题,人们对解决方案的看法也有所不同。 类级别的方法提供了最大的灵活性,并使规范保持简单。 但是,辩论仍在进行中:如果您有意见,请访问http://forum.hibernate.org/viewforum.php?f=26并说出:)

InfoQ :我们可以使用表达语言来处理错误消息和/或是否为消息插入点(在{x}和{y}之间输入数字)?

EB :是的,默认消息解析策略允许注入约束参数。

@Length(max = 50, message="{constraint.name.tooLong}")
String name;
constraint.name.tooLong = Names must not be longer than {max} characters

将显示以下消息:名称不得超过50个字符。

但这显然是专家组寻求反馈和建议的领域。 在Bean验证反馈论坛上已经开始进行一些讨论,以提供其他上下文信息。

同样如前所述,可以向Bean验证提供程序提供自定义消息解析策略:这是与现有Web和应用程序框架进行自然集成的关键。 我认为应用程序和Web框架比Bean验证框架拥有更多的可用信息,因此可以提供更好的变量插值和表达语言解析。

InfoQ :您打算在错误消息中支持超链接吗?如果可以,那么如何处理本地化问题(链接的位置可能是
例如在不同的区域设置不同)?

EB :您所描述的内容高度依赖表示框架。 呈现框架提供的自定义消息解析策略非常适合处理此类情况,因为呈现框架具有所有上下文知识(URL根,传递的参数等)。

InfoQ :如何在各层之间处理多语言方案? 例如,如果后端系统以一种语言(例如英语)生成错误,但我需要以另一种语言(例如广东话)向用户显示错误。

EB :这是一个非常有趣的问题,很遗憾,我没有所有要回答的问题,因为它涉及整个Java EE平台,而不仅仅是Bean验证。
如果希望使用粤语阅读,则后端系统不应以英语生成错误消息。 尽管规范尚未对其进行描述,但是专家组希望能够自定义用于给定验证调用的语言环境(可能通过基于线程的传播模型)。 应用程序框架将负责将语言环境从客户端传递到服务器端。

如您所见,应用程序框架(调用方)和Bean验证之间的集成将是提供整洁的用户体验的关键。 不幸的是(或幸运的是),此JSR专注于约束声明和验证。 但是,专家组意识到这一点,我们会尽力提供必要的扩展和集成点,以使消费者能够正确集成。

InfoQ :理想情况下,我希望能够使用相同的框架来处理我的所有验证(例如,从JavaScript的应用程序层到数据库)。 当前的规范离该目标有多近?

EB :在我看来,至关重要的是能够在这些异构层之间共享相同的约束定义。 如果可以重复使用相同的验证框架,那就更好了。

Bean验证是不可知的层,从表示层到DAO层的所有Java层都可以简单地将约束验证委派给Bean验证运行时。 让我们举几个例子:

  • 每当将实体添加到数据库或在数据库中更新实体时,Java Persistence都可以调用Bean验证
  • 业务组件可以在应用核心业务逻辑之前对一组数据调用Bean验证
  • 表示层可以在将表单提供的数据传递到域模型之前调用其验证逻辑
  • 在这种情况下,Bean验证是架构各部分所调用的验证运行时引擎。 因为约束放置在域模型类上并由所有层共享,所以相同的验证适用于所有方面。

对于Java以外的层来说,它变得更加复杂和有趣。 数据库是一个很好的例子。 在数据库模式中,某些约束是很有意义的(不是null,length等)。 Bean验证规范通过元数据请求API公开了一些约束的基本元数据信息。 Java Persistence可以加入该API,提取有用的信息,并将一些约束应用于数据库模式。

在表示方面,特别是在Web应用程序中,可以通过JavaScript代码施加一些约束。 它减少了到服务器的往返次数,并通过早期的错误反馈提供了更好的用户体验。 在这种情况下,可以采用两种方法。 表示小部件(例如JSF组件)可以从Bean验证请求API中提取约束元数据,并在JavaScript中应用相同的逻辑。 当然,并非所有约束都可以由该模型表达。 但是其中一些将应用于客户端。 这种方法的优点在于,客户端和服务器端都共享域模型中的约束声明,因此它们保持透明一致。 虽然我们不重用实际的约束实现,但是元数据API提供了一些提取约束定义并重用它的方法。 第二种方法是使用类似于GWT的方法:将Java代码转换为JavaScript:然后在客户端和服务器端共享相同的实现逻辑。

InfoQ :好的-假设我在Web应用程序中有一个电话号码字段。 该字段是必填字段,最大长度为40个字符,并且仅接受字母数字值。 我想使用JavaScript检查网络端的字段长度。 在数据库方面,我还将字段定义为CHAR40。 如果我想从Web层查找约束验证,我该怎么做以及如何返回? 您是否认为JPA 2的工作方式与此相同?

EB :您所描述的基本上是将约束导出到Java的边界之外。 为此,将Java世界与Web / JavaScript工作联系起来的框架需要:

  • 知道Web表单输入和域模型属性之间的链接
  • 可以访问约束描述

第一点是链接框架的作用。 可以通过检查表达式语言来实现(例如在JSF中),因为框架使用“ Java”(例如在Wicket中),因此可能发生。

第二点是因为链接框架可以从属性中查询Bean验证的元数据API并接收约束列表。 每个约束(除了实现验证逻辑之外)还描述了如何将其投影到一组预定义的静态约束维度上。 那是什么意思? 说每个约束都描述是否:

  • 它强制执行不可为空性,可为空性或不强制执行。
  • 它是否强制执行长度限制。
  • 它强制执行最大值还是不执行最大值。

等等。 这将需要表示框架中的一些工作来包含和使用Bean Validation API,但是它将为开发人员带来很多附加值。

与Java Persistence的集成及其生成数据库模式的方式几乎相同:只需将“ form input”一词替换为“ column”。

InfoQ :规范在很大程度上受到Hibernate Validation的影响,但是组概念似乎有些偏离。 您能否告诉我们一些有关此想法的来历以及如何使用它?

EB :规范从Hibernate Validation借鉴了很多,但也从许多不同的验证框架中汲取了一些想法。 话虽如此,最小化规范错误的最佳方法是基于现有的工作功能:事实上,规范中的大多数功能都是通过从头开始实施概念验证或分叉来进行测试的。Hibernate验证器,以确保它们能够飞行。

我不确切知道群组功能的出生地和出生方式,所以如果我记错了它,请原谅。 我知道Rifle长期以来都具有类似的功能,我记得Hibernate Validator用户要求这种功能。 通常,关于组和约束之间的依赖关系的难点在于,描述它们很快会变得非常非常冗长和复杂。 该规范试图在灵活性和简单性之间取得平衡。 我们已经在反馈论坛中开始了一些有趣的讨论,以尝试改进它。

在以下几种情况下,组非常重要:

  • 定义约束子集以按用例对它们进行分组(用户有效,并且提供了足够的信息以一键购买)
  • 验证用户提供的数据:并非同时提供所有数据。 给定对象可能仅部分有效
  • 某些约束应在其他约束之后进行验证,除非先前的验证通过,否则不要进行验​​证。 可能是因为它们在时间或CPU上很昂贵,或者是因为它们期望数据处于“正常”状态。

组为所有这些用例提供了声明式解决方案。 我们期望Java Persistence,JSF,Web Bean或任何应用程序框架将提供一种声明性的方式来请求特定于组的验证。

InfoQ :您如何与其他可能重叠的专家组合作? 例如在JPA2,Web Beans等中。

EB :严格来说,JSR 303与您提到的规范之间没有重叠,但是肯定有集成的机会。 尽管集成工作尚未正式开始,但303专家组的各种成员还是JPA 2,JSF 2和Web Beans专家组的成员。 我个人是JPA 2专家组的成员,并且一直在考虑Java持久性集成。 随着早期草案的发布,其他专家组可以发表评论并提供反馈,以使这种集成成为现实。

InfoQ :原型实现将在多久之前推出?

EB :实际上,社区击败了我们。 您已经可以在那里找到一些实现。 我知道http://code.google.com/p/agimatec-validation/
尽管不符合规范(尤其是API规范),但Hibernate Validator实现了规范背后的大多数概念,并探讨了我们刚刚讨论的前端到后端集成模型:

  • 它与Hibernate Core集成以同步数据库架构
  • 它通过以下方式与JBoss Seam和JSF集成: 标签。 该标签触发对表单属性的Hibernate Validator的调用,然后再将其传递给应用程序流的其余部分
  • 一些UI小部件会重用Hibernate Validator约束,并通过JavaScript调用将其应用于客户端

InfoQ :您在Java社区中寻找什么?

EB :我们非常渴望获得有关规范的反馈:

  • 满足应用程序开发人员需求的程度(易用性,用例)
  • 它如何满足框架开发人员的需求(集成点,可重用性)
  • 如何改善

我们已经不再使用基于电子邮件的反馈系统,而是开设了一个公共论坛 ,人们可以在这里进行互动,提出问题,提出替代解决方案。 这是更改和增强规格的最佳时机。 到目前为止,反馈非常好,很有趣,请继续:)

翻译自: https://www.infoq.com/articles/emmanuel_bernard_interview/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

emmanuel字体书写

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐