检查Controller或Service层中的前提条件

gen*_*ejo 17 validation service spring controller

我正在使用Google的Preconditions类来验证用户的输入数据.
但我担心使用Preconditions类检查用户输入数据的最佳位置在哪里.
首先,我在Controller中编写了验证检查代码,如下所示:

@Controller
...
public void register(ProductInfo data) {
    Preconditions.checkArgument(StringUtils.hasText(data.getName()),
        "Empty name parameter.");
    productService.register(data);
}

@Service
...
public void register(ProductInfo data) {
    productDao.register(data);
}
Run Code Online (Sandbox Code Playgroud)

但我认为registerService层中的方法将使用另一个Controller方法,如下所示:

@Controller
...
public void register(ProductInfo data) {
    productService.register(data);
}
public void anotherRegister(ProductInfo data) {
    productService.register(data);
}

@Service 
...
public void register(ProductInfo data) {
    Preconditions.checkArgument(StringUtils.hasText(data.getName()),
        "Empty name parameter.");
    productDao.register(data);
}
Run Code Online (Sandbox Code Playgroud)

另一方面,服务层的方法将仅用于一个控制器.
我很困惑.哪种方法可以更好地检查控制器或服务中的前提条件?
提前致谢.

Ada*_*ent 27

理想情况下,你会在两个地方都这样做.但是你混淆了两件不同的事情:

  • 验证(带错误处理)
  • Defensivie编程(又名断言,又称合同设计).

你绝对应该在服务器中进行控制器验证防御性编程.这就是原因.

您需要验证表单和REST请求,以便向客户端发送合理的错误.这包括哪些字段是坏的,然后进行错误消息的本地化...等...(如果ProductInfo.name属性为null,您当前的示例将向我发送带有堆栈跟踪的可怕的500错误消息).

Spring有一个验证控制器中对象解决方案.

防御性编程在服务层完成但不验证,因为您无权访问区域设置以生成正确的错误消息.有些人会这样做,但Spring并没有真正帮助你.

验证未在服务层中完成的另一个原因是ORM通常已通过JSR Bean Validation规范(hibernate)执行此操作,但它不会生成合理的错误消息.

一种策略人做是创建一个自定义的抛出衍生有自己的前提条件utils的图书馆RuntimeExceptions,而不是番石榴(和公共郎)IllegalArgumentExceptionIllegalStateException,然后try...... catch在控制器中的异常将它们转换为验证错误消息.