后端门卫 - 参数校验方式总结

前言

在我们日常开发的工作中 一定会遇到参数接收 有些开发可能不会太关注参数校验这方面 其中一个原因是感觉不会造成什么大事故 还有就是前端比较负责 参数传递比较规范 但是作为开发还是要做好参数校验 减少问题的出现本文整理了一些常用的参数校验的方法 可能不是很全 但是也有一定的帮助

1.手动校验

手动校验是最基础的参数校验方法,我们通过编写自定义的校验逻辑来验证参数的合法性例如:

public void updateUser(User user) {
    if (user == null) {
        throw new IllegalArgumentException("用户不能为空");
    }
    if (user.getId() <= 0) {
        throw new IllegalArgumentException("无效的用户ID");
    }
    if (StringUtils.isEmpty(user.getName())) {
        throw new IllegalArgumentException("用户姓名不能为空");
    }
}

这种方法的优点是灵活性高,可以根据具体需求定制校验规则。开发人员可以根据参数类型、长度、格式等条件进行校验。

优点:

  • 灵活性高,可以根据具体需求编写自定义的校验逻辑。
  • 可以针对不同的参数类型进行精细化的校验。
  • 可以根据实际业务场景定制校验规则。

缺点:

  • 需要手动编写大量的校验逻辑,容易出现遗漏和错误。
  • 代码冗余,可读性差。
  • 难以应对复杂的校验逻辑和变化的需求。

适用场景:

  • 简单的参数校验场景,校验规则简单且不频繁变动。

2.使用注解校验

注解校验是一种简化参数校验的方法,通过在实体类的属性上添加注解来定义校验规则。框架会根据注解配置自动进行参数校验,大大减少了手动编写校验逻辑的工作量。常用的注解校验框架有Hibernate Validator、Spring Validation等。

public class User {
    @NotNull(message = "用户不能为空")
    private Integer id;

    @NotEmpty(message = "用户姓名不能为空")
    private String name;
}

public void updateUser(@Valid User user) {
    // 代码。。。
}

优点:

  • 减少了手动编写校验逻辑的工作量,提高了开发效率。
  • 注解规范明确,易于理解和维护。
  • 可以利用框架提供的丰富注解进行各种校验规则的定义。

缺点:

  • 对复杂校验场景的支持相对有限,定制化需求可能不太容易实现。

适用场景:

  • 简单到中等复杂的参数校验场景,校验规则相对固定。

3.使用验证器类

验证器类是一种将校验逻辑与实体类分离的方法,通过编写验证器类来实现参数校验。验证器类负责校验逻辑的编写,将校验结果返回给调用方。

public interface Validator<T> {
    void validate(T object) throws ValidationException;
}

public class UserValidator implements Validator<User> {
    public void validate(User user) throws ValidationException {
        if (user == null) {
            throw new ValidationException("用户不能为空");
        }
        if (user.getId() <= 0) {
            throw new ValidationException("无效的用户ID");
        }
        if (StringUtils.isEmpty(user.getName())) {
            throw new ValidationException("用户姓名不能为空");
        }
 
    }
}

public void updateUser(User user) {
    UserValidator validator = new UserValidator();
    validator.validate(user);
}

优点:

  • 将校验逻辑与实体类分离,提高了代码的可维护性和可测试性。
  • 支持更复杂的校验逻辑,易于定制化。

缺点:

  • 需要编写额外的验证器类,增加了代码量。

适用场景:

  • 复杂的参数校验场景,需要灵活的定制校验规则。

4.使用第三方库

除了手动编写校验逻辑外,还可以使用第三方库来简化参数校验的过程。常用的第三方库有Apache Commons Validator、Guava Preconditions等。这些库提供了丰富的校验方法和工具函数,能够满足各种校验需求。

public void updateUser(User user) {
    Preconditions.checkNotNull(user, "用户不能为空");
    Preconditions.checkArgument(user.getId() > 0, "无效的用户ID");
    Preconditions.checkArgument(!Strings.isNullOrEmpty(user.getName()), "用户姓名不能为空");
}

优点:

  • 简化了参数校验的代码,提供了丰富的校验方法和工具函数。

缺点:

  • 某些库可能功能较为单一,无法满足复杂的校验需求。

适用场景:

  • 简单到中等复杂的参数校验场景,校验规则相对固定,希望通过第三方库简化代码。

5.数据流检查

数据流检查也是一种方式,但是相对于前面不是很常用,主要关注参数在整个数据流中的安全性和正确性。它涉及参数的输入源、输出源以及与其他系统的数据交互

例如:

public class DataFlowValidationDemo {

    public static void main(String[] args) {
        // 模拟数据流
        Map<String, Object> dataFlow = new HashMap<>();
        dataFlow.put("input", getInputData());
        dataFlow.put("process1", null);
        dataFlow.put("process2", null);
        dataFlow.put("output", null);

        // 数据流检查
        boolean isDataValid = validateDataFlow(dataFlow);

        // 输出结果
        if (isDataValid) {
            System.out.println("数据流校验通过");
            processDataFlow(dataFlow);
            System.out.println("数据流处理完成");
        } else {
            System.out.println("数据流校验未通过");
        }
    }

    private static boolean validateDataFlow(Map<String, Object> dataFlow) {
        // 检查输入数据
        Object inputData = dataFlow.get("input");
        if (inputData == null) {
            System.out.println("输入数据为空");
            return false;
        }

        // 检查处理过程1的结果
        Object process1Result = dataFlow.get("process1");
        if (process1Result == null) {
            System.out.println("处理过程1结果为空");
            return false;
        }

        // 检查处理过程2的结果
        Object process2Result = dataFlow.get("process2");
        if (process2Result == null) {
            System.out.println("处理过程2结果为空");
            return false;
        }

        // 检查输出数据
        Object outputData = dataFlow.get("output");
        if (outputData == null) {
            System.out.println("输出数据为空");
            return false;
        }

        return true;
    }

    private static void processDataFlow(Map<String, Object> dataFlow) {
        // 在实际应用中,可以进行具体的数据处理操作
        System.out.println("数据流处理中...");
        // ...
    }

    private static Object getInputData() {
        // 模拟获取输入数据的逻辑
        return "Input Data";
    }

}

优点:

  1. 安全性增强:数据流检查可以确保参数在整个数据流中的安全性,防止恶意数据的注入和篡改,保护系统和数据的安全。
  2. 有效性验证:通过对参数在数据流中的合法性进行检查,可以确保参数在数据交互过程中的有效性和正确性,减少数据错误和异常情况的发生。
  3. 防御性编程:数据流检查可以作为一种防御性编程的手段,提前发现和处理可能导致问题的参数,增加系统的健壮性和容错性。

弊端:

  1. 复杂性增加:数据流检查需要对参数在整个数据流中的流向和处理逻辑进行分析和验证,可能会增加代码的复杂性和开发成本。
  2. 维护困难:如果数据流发生变化,需要相应地调整和更新数据流检查的逻辑,可能会增加维护的难度。
  3. 性能开销:数据流检查可能会涉及多次数据的读取和处理,可能会对系统的性能产生一定的开销。

使用场景:

  1. 敏感数据处理:对于包含敏感信息的参数,如用户身份证号、密码等,需要通过数据流检查确保其安全性和合法性。
  2. 数据交互场景:在与其他系统进行数据交互的接口中,需要对参数进行数据流检查,以确保数据的正确传递和处理。
  3. 高风险操作:在涉及高风险操作的接口或功能中,如资金交易、权限管理等,需要进行数据流检查以提高系统的安全性和可靠性。

6. 数据库约束

这个可以配合使用通过在数据库层面设置参数的约束条件,如字段的长度、数据类型、唯一性等。通过数据库的约束可以确保数据的完整性和一致性,但是要注意处理异常信息。

总结

在上文我们介绍了四种常见的后端参数校验方法:手动校验注解校验验证器类使用第三方库。每种方法都有自己的优点和适用场景。选择合适的参数校验方法取决于具体的需求和项目规模。

无论采用何种方法,参数校验的目标始终是保证系统的安全性和可靠性。在日常工作中合理的参数校验能够避免潜在的安全风险和数据异常,应该根据项目的需求和团队的技术能力选择最适合的参数校验方法,并结合良好的编码规范和团队协作,保证参数校验的有效性和一致性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

变成派大星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值