- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我们都知道,Spring MVC 通常与 Hibernate Validator 和 JSR-303 集成得很好。但是,正如有人所说,Hibernate Validator 只是 Bean Validation 的东西,这意味着应该将更复杂的验证推到数据层。此类验证的示例:业务 key 唯一性、记录内依赖性(这通常指向数据库设计问题,但我们都生活在一个不完美的世界中)。即使是像字符串字段长度这样的简单验证也可能由一些 DB 值驱动,这使得 Hibernate Validator 无法使用。
所以我的问题是,Spring、Hibernate 或 JSR 是否提供了一些东西来执行如此复杂的验证?在基于 Spring 和 Hibernate 的标准 Controller-Service-Repository 设置中是否有一些已建立模式或技术来执行此类验证?
更新:让我说得更具体一些。例如,有一个表单向 Controller 的 save
方法发送 AJAX 保存请求。如果出现一些验证错误——无论是简单的还是“复杂的”——我们应该用一些 json 指示有问题的字段和相关错误返回浏览器。对于简单的错误,我可以从 BindingResult
中提取字段(如果有)和错误消息。对于“复杂”错误,您会建议什么基础设施(可能是特定的,而不是临时异常(exception)?)?使用异常处理程序对我来说似乎不是一个好主意,因为在 save
方法和 @ExceptionHandler
之间分离单个验证过程会使事情变得复杂。目前我使用一些临时异常(例如,ValidationException
):
public @ResponseBody Result save(@Valid Entity entity, BindingResult errors) {
Result r = new Result();
if (errors.hasErrors()) {
r.setStatus(Result.VALIDATION_ERROR);
// ...
} else {
try {
dao.save(entity);
r.setStatus(Result.SUCCESS);
} except (ValidationException e) {
r.setStatus(Result.VALIDATION_ERROR);
r.setText(e.getMessage());
}
}
return r;
}
你能提供一些更优化的方法吗?
最佳答案
是的,Exception throwing 的 Java 模式已经确立了良好的旧模式。
Spring MVC 集成的很好(代码示例可以直接跳到我回答的第二部分)。
您所说的“复杂验证”实际上是异常(exception):业务 key 唯一性错误、低层或数据库错误等。
验证应该发生在表示层上。它基本上是关于验证提交的表单字段。
我们可以将它们分为两种:
1) 轻度验证(使用 JSR-303/Hibernate 验证):检查提交的字段是否具有给定的 @Size
/@Length
,它是 @NotNull
或 @NotEmpty
/@NotBlank
,检查它是否具有 @Email
格式等。
2) 重度验证或复杂验证更多的是关于字段验证的特定情况,例如跨字段验证:
fieldA
、fieldB
和fieldC
。每个字段可以单独为空,但至少有一个字段不能为空。userAge
字段的值小于 18,则 responsibleUser
字段不能为空且 responsibleUser
的年龄必须超过21.这些验证可以通过 Spring Validator implementations 来实现。 , 或 custom annotations/constraints .
现在我明白了,有了所有这些验证工具,再加上 Spring 完全没有侵入性并且可以让你做任何你想做的事情(无论好坏),人们可能会想使用“验证锤”来任何与错误处理模糊相关的内容。
它会起作用:仅通过验证,您可以检查 validator/注释中的所有可能问题(并且几乎不会在较低层抛出任何异常)。这很糟糕,因为你祈祷你考虑过所有的情况。您不会利用 Java 异常来简化逻辑并通过忘记检查是否有错误来减少出错的机会。
所以在 Spring MVC 世界中,不应该将验证(即 UI 验证)误认为是低层 异常,例如有 Service 异常或 DB 异常(关键唯一性等)。
有些人认为“天哪,所以在我的 Controller 中,我必须一一检查所有可能的已检查异常,并为每个异常考虑一个消息错误?没办法!”。我是那些人的其中一个。 :-)
在大多数情况下,只需使用一些通用的检查异常类,所有异常都会扩展。然后只需在 Spring MVC Controller 中使用 @ExceptionHandler 处理它和一般错误消息。
代码示例:
public class MyAppTechnicalException extends Exception { ... }
和
@Controller
public class MyController {
...
@RequestMapping(...)
public void createMyObject(...) throws MyAppTechnicalException {
...
someServiceThanCanThrowMyAppTechnicalException.create(...);
...
}
...
@ExceptionHandler(MyAppTechnicalException.class)
public String handleMyAppTechnicalException(MyAppTechnicalException e, Model model) {
// Compute your generic error message/code with e.
// Or just use a generic error/code, in which case you can remove e from the parameters
String genericErrorMessage = "Some technical exception has occured blah blah blah" ;
// There are many other ways to pass an error to the view, but you get the idea
model.addAttribute("myErrors", genericErrorMessage);
return "myView";
}
}
简单、快速、简单、干净!
当您需要为某些特定异常显示错误消息时,或者由于设计不佳的遗留系统无法修改而无法提供通用顶级异常时,只需添加其他 @ExceptionHandler
s.
另一个技巧:对于不太困惑的代码,您可以使用
@ExceptionHandler({MyException1.class, MyException2.class, ...})
public String yourMethod(Exception e, Model model) {
...
}
当我说“来自 UI 的错误”时,我的意思是“用户在他的表单中输入了错误”。
引用资料:
关于java - Spring MVC + hibernate : data validation strategies,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12660262/
只是想知道这些结构之间有什么区别(text、data、rodata、bss 等)在链接描述文件中: .data : { *(.data) } .data : { *(.data*) }
Data 定义为其核心功能之一 gfoldl : gfoldl :: (Data a) => (forall d b. Data d => c (d -> b) -> d -> c b)
以下之间有什么区别:data-sly-use、data-sly-resource、data-sly-include 和 数据-sly-模板?我正在阅读 Sightly AEM 上的文档,我非常困惑。
我有一个 Spring Boot、Spring Data JPA (hibernate) Web 应用程序,并且想引入文本搜索功能。 我理解以下内容 hibernate search 或 spring
我不知道我的代码有什么问题。我读了其他有同样问题的人的一些问题,但没有找到答案。当我尝试编译时出现以下错误: ||In function 'main':| |35|error: expected ex
我不太确定为什么会收到此错误或其含义。我的数据框称为“数据”。 library(dplyr) data %>% filter(Info==1, Male==1) %>% lm(CFL_
我一直在 GitHub 等更现代的网站上看到这些属性,它们似乎总是与自定义的弹出窗口一致,如 title 属性。 Option 1 Option 2 Option 3 Option 4 我在 HTML
如何用 iCloud Core Data 替换我现有的 Core Data?这是我的持久商店协调员: lazy var persistentStoreCoordinator: NSPersistent
我一直在 GitHub 等更现代的网站上看到这些属性,它们似乎总是与自定义的弹出窗口一致,如 title 属性。 Option 1 Option 2 Option 3 Option 4 我在 HTML
我正在通过 this project 在 Android 上摆弄 node.js ,我需要一种方法将 js 文件部署到私有(private)目录(以隐藏源代码,防止用户篡改),该目录也物理存在于文件系
大家好我有点沮丧,所以我希望得到一些帮助。我的项目在 SwiftUI 中。我想使用图像选择器将图像保存到 Core Data。我实现了让 ImagePicker 工作,但我正在努力转换 Image -
我有以下数据和代码: mydf grp categ condition value 1 A X P 2 2 B X P 5
我一直在努力解决这个问题,但我根本找不到任何解决问题的方法。希望这里有人可以提供帮助。 我正在尝试为具有以下结构的某些数据创建个人选择矩阵: # A tibble: 2,152 x 32 a
我了解 Data.Map.Lazy 和 Data.Map.Strict 是不同的。但是,当您导入 Data.Map 时,您究竟导入了什么:严格的、惰性的还是两者的组合? 最佳答案 懒人。看着docs
我正在开发一个 C 程序,用于从 BerkeleyDB DBTree 数据库中提取数据值与特定模式匹配的记录。我创建数据库,打开它,将键的 DBT 和数据的另一个 DBT 清零,将 DBT 标志设置为
所以我有以下成员(member)历史表 User_ID | Start date | End Date | Type(0-7) | ---------------------------
随着最近推出的包dataframe ,我认为是时候正确地对各种数据结构进行基准测试,并突出每种数据结构的优势。我不是每个人的不同优势的专家,所以我的问题是,我们应该如何对它们进行基准测试。 我尝试过的
我有来自 API 的数据,但无法将数组中的数据设置为 vue.js 中的 this.data这是来自 API 的数据(JSON) 你能告诉我这个语法吗 {"id":1613, "name_org":"
在 Vue.js到目前为止,我已经找到了两种定义数据的方法:data: {} 和 data() { return; }. data: { defaultLayout: 'default' }
我正在研究Spring Data Rest Services,并在自定义拦截器中遇到一些问题。之前我使用spring-data-rest-webmvc 2.2.0并以以下方式添加了拦截器。 publi
我是一名优秀的程序员,十分优秀!