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

业务逻辑验证模式和建议

汪兴旺
2023-03-14
问题内容

我的应用程序中有两层验证。首先是由bean验证API执行的实体验证(例如,必填字段)。第二层是业务逻辑验证。例如,用户有一个帖子。用户只有自己是该帖子的创建者,并且帖子评级小于50,才能删除该帖子。因此,我必须执行以下操作:

if (post.getCreator().equals(session.getUser())) {
  if (post.getRating() < 50) {
    postRepository.delete(post);
  } else errors.add(400, "Cant delete post with rating 50 or higher")
} else errors add (400, "You should be owner of the post")

我不喜欢这种方式,因为这种条件被重用,而且我不得不重复代码。此外,如果条件数大于5左右,那么阅读和理解代码就变得不现实。

此外,标准的Spring Validator不会很有帮助,因为我必须针对不同操作(例如删除和更新)对一个实体进行不同的验证

因此,我正在寻找一种以更智能的方式(可能是模式)执行此操作的方法,如果有人可以给我提示,我将不胜感激。

预先感谢!


问题答案:

您可以使用策略模式。

可以将每个条件建模为一个函数,该函数需要发布和会话,并可能返回错误:

Post -> PostContext -> Optional<String>

您可以用一个接口来表示:

@FunctionalInterface
public interface ValidationCondition {

    Optional<String> validate(final Post post, final Session session);
}

因此,例如:

public class CreatorValidation implements ValidationCondition {

    public Optional<String> validate(final Post post, final Session session) {
        if (post.getCreator().equals(session.getUser()) {
            return Optional.empty();
        }
        return Optional.of("You should be the owner of the post");
    }
}

然后,您可以将每个验证存储在列表中:

final List<ValidationCondition> conditions = new ArrayList<>();

conditions.add(new CreatorValidation());
conditions.add(new ScoreValidation());
// etc.

使用该列表,可以批量应用验证:

final List<String> errors = new ArrayList<>();

for (final ValidationCondition condition : conditions) {
    final Optional<String> error = condition.validate(post, session);
    if (error.isPresent()) {
        errors.add(error.get());
    }
}

使用Java 8 lambda,可以内联声明以下代码:

final ValidationCondition condition = (post, session) -> {
    // Custom logic
});


 类似资料:
  • 综述 应用程序必须确保只有逻辑合法的数据才能在前端输入和直接传输到服务器端。只对数据进行本地验证可能是应用层序在服务器端遭到攻击,比如通过代理或传输途中的其他系统。这不同于进行简单的边界数据分析(BVA),验证更加困难,大多数情况下不能简单在输入端进行验证,通常需要其他系统进行检查。 举例说明:应用程序可能需要你的社会安全号码(SSN)。在BAV中,应用程序应该在数据输入时候检查文件形式和语法(在

  • 我正在为一个web应用程序实现一个相当复杂的输入验证,它应该输入一个ID,并将调用其他几个系统,以便在持久化包含该ID的对象之前检查该ID是否有效。我想使用bean验证,但后来我发现自己专门创建了一个bean来允许这种验证发生。事实上,为了进行远程服务调用,我不仅需要向验证器提供ID,还需要提供一些上下文信息。 您认为bean-validation始终是正确的验证位置吗,即使它很复杂并且需要Bea

  • 综述 在多功能的动态web应用程序中测试业务逻辑漏洞需要用非常规手段来思考。如果应用认证机制原先以1、2、3的步骤依次执行的验证身份目的来开发,万一用户从步骤1直接跳到步骤3会发生什么?用更加简单的例子来说,在打开失败、权限拒绝或仅仅500的错误的情况下,应用程序是否依然能够提供访问权限? 可以举出许多例子,但是不变的思想是“跳出常规思维”。这种类型的漏洞无法被漏洞扫描工具探测到,依赖于渗透测试人

  • 问题内容: 软件体系结构中的域对象和域服务是什么?我不熟悉它们,或者它们与业务逻辑层有何不同? 问题答案: 不同的人以不同的方式使用这些术语,但这是我的看法: 1)“业务”和“域”大致是同义词。“域”更为通用,因为它不会假设您正在编写业务应用程序。因此,如果我们正在编写科学应用程序或游戏,则可能更喜欢将代码的相关部分称为“域”代码,而不是“业务”代码。因此,在本说明的其余部分中,我将使用“域”,因

  • 1.1  概述 业务逻辑模块主要用于编写业务逻辑,一般包含三个子模块:action(定义action和procedure)、code(业务逻辑的实现,一般使用java实现,有src,dsrc,lib)、fn(函数定义)。 1.2  Action定义 语法: <action name=" n" global="true" log-enabled="true" procedure=" "> <参

  • 在实现访问服务器和与本地数据库交互之后,是时候把事情整合起来了。逻辑步骤如下: 从数据库获取数据 检查是否存在对应星期的数据 如果有,返回UI并且渲染 如果没有,请求服务器获取数据 结果被保存在数据库中并且返回UI渲染 但是我们的commands不应该去处理所有这些逻辑。数据源应该是一个具体的实现,这样就可以被容易地修改,所以增加一些额外的代码,然后把command从数据访问中抽象出来听起来是个不