如何用Hibernate Validator验证重写的方法参数?
关于这个文档,我明白如果我的GroupService实现了GroupManager并覆盖了它的方法,那么我不能用验证约束来注释,因为Hibernate验证器不允许它(这被证明是Liskov替换原理)。 我的意思是做类似的事情
public class GroupService implements GroupManager{
@Override
public List<String> findUsersInGroup(@NotNull String groupName) {
...
}
}
然后会引发ConstraintDeclarationException
,对吧? 所以解决方案显然是将这些限制放在界面上,但在这种情况下:
GroupManager
属于Spring Security
)。 我该怎么做呢? Hibernate Validator
迫使我“弄脏”界面 我可能无法访问modificate接口(因为GroupManager属于Spring Security)。 在这种情况下我应该怎么做?
您可以使用xml配置,因为JSR-303(Bean验证)支持它。 例如
<constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"
xmlns="http://jboss.org/xml/ns/javax/validation/mapping">
<default-package>org.springframework.security.provisioning</default-package>
<bean class="GroupManager" ignore-annotations="true">
<method name="findUsersInGroup">
<parameter type="java.lang.String">
<constraint annotation="javax.validation.constraints.NotNull"/>
</parameter>
</method>
</bean>
</constraint-mappings>
请参阅hibernate文档中的xml配置一章。
我认为这些验证约束不应该影响接口,因为它们是其实现的一部分
正如hibernate文档所述
当在子类型方法中重写方法时,参数约束只能在基类型中声明。 这种限制的原因是, 类型客户端要满足的前提条件不能在子类型中加强 (基类型客户甚至可能不知道)。
子类型不应加强方法前提条件。 如果你说你的子类型GroupService
不允许一个null
参数,你可能会加强前提条件。 例如,使用GroupManager
的客户端可能不知道(也不应该知道)它是GroupService
。 GroupManager
界面不会对参数进行任何限制。 所以,如果你这样做,你打破了以前的客户代码。 这违反了Liskov替代原则。
可悲的是, GroupManager
javadoc不限制参数。 因此,法律实施必须处理所有情况。
一般来说...当我定义方法时,我会应用这些规则
null
。 这些简单的规则帮助我为客户创建一个清晰的API。
编辑
我认为可能我有impl“A”和impl“B”(都实现相同的接口),其中impl“A”比“B”有更多(和不同的)验证。
如果是这样,他们不具有相同的接口或API。 你看到的是两者都有相同的方法签名。 但是两个相同的方法签名不能共享相同的API合同。 当我谈论一个界面时,我想到的是合同而不仅仅是签名。 想象一下下面的界面:
public class Container {
/**
* @return a non-empty collection of elements.
*/
public Collection<Element> getElements();
}
在这种情况下,合法的客户端代码会是
Container container = ....;
Element firstElement = container.getElements().iterator().next();
因为合同说它返回一个非空集合。
如果我们更改javadoc并因此更改后置条件...
/**
* @return a collection of elements.
*/
public Collection<Element> getElements();
以前合法的客户端代码不再适用。
我只是通过这个例子来展示合同和方法签名之间的区别。
这里可以找到详细而且非常好的解释。
由于GroupManager javadoc不限制参数,合法的impl必须处理每种情况'? 这是验证方法内的参数?
是。 如果接口没有为参数添加任何限制,则实现必须处理每个状态,因为客户端可能会在任何状态下传递参数。
链接地址: http://www.djcxy.com/p/86649.html上一篇: How to validate overridden methods parameters with Hibernate Validator?