当前位置: 首页 > 面试题库 >

Spring验证,如何让PropertyEditor生成特定的错误消息

松增
2023-03-14
问题内容

我正在使用Spring进行表单输入和验证。表单控制器的命令包含正在编辑的模型。模型的某些属性是自定义类型。例如,“人”的社会保险号是自定义的SSN类型。

public class Person {
    public String getName() {...}
    public void setName(String name) {...}
    public SSN getSocialSecurtyNumber() {...}
    public void setSocialSecurtyNumber(SSN ssn) {...}
}

并在Spring表单编辑命令中包装Person:

public class EditPersonCommand {
    public Person getPerson() {...}
    public void setPerson(Person person) {...}
}

由于Spring不知道如何将文本转换为SSN,因此我向表单控制器的活页夹注册了客户编辑器:

public class EditPersonController extends SimpleFormController {
    protected void initBinder(HttpServletRequest req, ServletRequestDataBinder binder) {
        super.initBinder(req, binder);
        binder.registerCustomEditor(SSN.class, "person.ssn", new SsnEditor());
    }
}

SsnEditor只是一个java.beans.PropertyEditor可以将文本转换为SSN对象的自定义:

public class SsnEditor extends PropertyEditorSupport {
    public String getAsText() {...} // converts SSN to text
    public void setAsText(String str) {
        // converts text to SSN
        // throws IllegalArgumentException for invalid text
    }
}

如果setAsText遇到无效且无法转换为SSN的文本,则它将抛出IllegalArgumentException(根据PropertyEditor
setAsText规范)。我遇到的问题是(通过PropertyEditor.setAsText())文本到对象的转换发生
调用Spring验证程序 之前
。当setAsText抛出IllegalArgumentException,春只显示在定义的一般错误消息errors.properties。我想要的是一条特定的错误消息,具体取决于输入的SSN无效的确切原因。PropertyEditor.setAsText()将确定原因。我尝试将错误原因文本嵌入的文本中IllegalArgumentException,但是Spring只是将其视为一般错误。

有针对这个的解决方法吗?重复一遍,我想要的是PropertyEditor在Spring表单上由to
生成的特定错误消息。我能想到的唯一替代方法是将SSN作为文本存储在命令中,并在验证器中执行验证。文本到SSN对象的转换将在表单的中进行onSubmit。这不太理想,因为我的表单(和模型)具有许多属性,并且我不想创建和维护一个命令,该命令具有每个模型属性作为文本字段。

上面只是一个示例,我的实际代码不是Person / SSN,因此无需回答“为什么不将SSN存储为文本…”


问题答案:

您正在尝试在活页夹中进行验证。那不是活页夹的目的。绑定器应该将请求参数绑定到您的支持对象,仅此而已。属性编辑器将字符串转换为对象,反之亦然-
它并非旨在执行其他任何操作。

换句话说,您需要考虑关注点的分离-您正在尝试将功能扩展到一个对象,而该对象只可以将字符串转换为对象,反之亦然。

您可以考虑将SSN对象分解为易于绑定的多个可验证字段(字符串对象,基本对象(如日期)等)。这样,您可以在绑定后使用验证器来验证SSN是否正确,也可以直接设置错误。使用属性编辑器,您将引发IllegalArgumentException,Spring会将其转换为类型不匹配错误,因为这就是事实-
字符串与预期的类型不匹配。仅此而已。另一方面,验证者可以执行此操作。只要填充了SSN实例,就可以使用spring绑定标签绑定到嵌套字段-
必须先使用new()对其进行初始化。例如:

<spring:bind path="ssn.firstNestedField">...</spring:bind>

但是,如果您确实想坚持下去,请让属性编辑器保留错误列表-
如果要抛出IllegalArgumentException,请将其添加到列表中,然后抛出IllegalArgumentException(如果需要,请重新捕获)。因为您可以在与绑定相同的线程中构造属性编辑器,所以如果您简单地覆盖属性编辑器的默认行为,则这将是线程安全的-
您需要找到用于绑定的钩子并覆盖它-
执行相同的属性编辑器现在要进行的注册(除了相同的方法外,以便可以保留对编辑器的引用),然后在绑定结束时,如果提供了公共访问器,则可以通过从编辑器中检索列表来注册错误。
。检索到列表后,您可以对其进行处理并相应地添加错误。



 类似资料:
  • 我有一个案例,我想对endpoint的@Request estParams进行一些输入验证。 我知道Validator和Custom Validator,我目前的策略意味着围绕Request estParams创建一个包装器对象,一个自定义验证器并应用类级别的注释来触发自定义验证。 我的问题是,自定义验证正在实现ConstraintValidator,这意味着验证器将返回true或false,Sp

  • 我为Money类编写了一个自定义Hibernate验证约束: 它工作正常,除了错误信息。我看到了非常奇怪的行为:找到了资源包,消息按名称解析,但它被包裹在特殊的字符中,如果消息不能按名称解析,通常会出现这些字符: 此处

  • 我在数据库上实现查询层,使用和Spring Boot项目在sql数据库上执行CRUD操作。在GraphQL模式中,我提到了一些必须的字段,当这些字段在查询中没有提到时,它会以默认格式返回状态代码的错误消息。 错误: 这是我的代码与层架构模式 控制器: 服务: 配置: BookDataFetcher: 上面的代码按预期工作,但我这里的问题是如何自定义错误消息?在错误消息中,我想提及状态,因为这是来自

  • 问题内容: 我想自定义弹簧验证错误 但是我做不到。要采取的步骤是什么? 问题答案: 该JSR 303的默认邮件插补算法,您可以通过提供捆绑命名的资源来定制信息。在类路径中创建一个文件,其中包含: 这将更改@Size约束的默认消息,因此您应该使用@Size约束而不是特定于Hibernate的@Length约束。 您可以更改特定约束实例的消息,而不是更改所有约束的默认消息。message在约束上设置属

  • 我正在尝试构建一个工具来验证特定的XML并输出人类可读的结果。我现有的PHP代码使用DOMDocument::模式验证来根据. xsd文件验证XML,但是错误消息不是很友好。 例如,假设我的XML看起来像下面的示例,纬度应该是十进制: 我当前收到的错误消息是: 文档::模式验证():元素'纬度':"不是原子类型'xs: decimal'的有效值。 我想说: XML第#5行出错:此人“Bret”的地

  • 对于错误的响应,是否可能在响应中返回验证注释消息?我认为这是可能的,但我注意到我们的项目没有给出详细的不良请求信息。 如果请求缺少IDField,我希望返回“IDField is required”。我用的是泽西2.0。我看到的回应是...