首页 > 解决方案 > 结合规范和防止 NullPointerException 和 IllegalArgumentException

问题描述

我尝试结合 8 个类似的标准来进行简单的查询。

我写了一个类似上面的方法

private Specification<CustomerHeaderParameter> buildCustomerHeaderParameterSpecifications(String status, String customerType, Integer segment, String module, String cardType, String processType, String rewardType, Integer intervalMin, Integer intervalMax) {

    Specification<CustomerHeaderParameter> result = Specification.where(withStatus(StatusCode.getEnum(status)));
    if (!StringUtils.isEmpty(customerType)) result.and(withCustomerType(CustomerType.getEnum(cardType)));
    if (segment != null) result.and(withSegment(SegmentParameterNumber.valueOf(segment)));
    if (!StringUtils.isEmpty(module)) result.and(withModule(ModuleType.valueOf(module)));
    if (!StringUtils.isEmpty(cardType)) result.and(withCardType(CardType.getEnum(cardType)));
    if (!StringUtils.isEmpty(processType)) result.and(withProcessType(ProcessType.valueOf(processType)));
    if (!StringUtils.isEmpty(rewardType)) result.and(withRewardType(RewardType.valueOf(rewardType)));
    if (intervalMin != null && intervalMax != null) result.and(inInterval(intervalMin, intervalMax));

    return result;
}

但是在这里第一行可以产生 NullPointerException 或 IllegalArgumentException 如果 status 为 null 或不同于枚举值,因为我的 Enum 类都类似于

public enum StatusCode {
    ACTIVE("A"), PASSIVE("P");

    private String value;

    StatusCode(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public static StatusCode getEnum(String value) {
        return Arrays.stream(values()).filter(v -> v.getValue().equalsIgnoreCase(value)).findFirst().orElseThrow(IllegalArgumentException::new);
    }
}

我的静态方法类似于

static Specification<CustomerHeaderParameter> withStatus(StatusCode status) {
    return (param, cq, cb) -> cb.equal(param.get(STATUS_CODE), status);
}

如果方法参数为 null 或与我的枚举中的值不同,如何防止出现异常?

或一般性问题;结合规范的最佳实践是什么?

标签: javaspringspring-bootspring-data-jpaspring-data

解决方案


我通过自定义规范类解决了问题

public class CustomerHeaderParameterSpecification implements Specification<CustomerHeaderParameter> {

    private StatusCode status;
    private CustomerType customerType;
    private SegmentParmNumber segment;
    private ModuleType module;
    private CardType cardType;
    private ProcessType processType;
    private RewardType rewardType;
    private Integer min, max;


    public CustomerHeaderParameterSpecification(StatusCode status, CustomerType customerType, SegmentParmNumber segment, ModuleType module, CardType cardType, ProcessType processType, RewardType rewardType, Integer min, Integer max) {
          this.status = status;
          this.customerType = customerType;
          this.segment = segment;
          this.module = module;
          this.cardType = cardType;
          this.processType = processType;
          this.rewardType = rewardType;
          this.min = min;
          this.max = max;
    }

    @Override
    public Predicate toPredicate(Root<CustomerHeaderParameter> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

        List<Predicate> predicates = new ArrayList<>();
        if (this.status != null) predicates.add(criteriaBuilder.equal(root.get(STATUS_CODE), status));
        if (this.customerType != null) predicates.add(criteriaBuilder.equal(root.get(CUSTOMER_TYPE), customerType));
        if (this.segment != null) predicates.add(criteriaBuilder.equal(root.get(SEGMENT_PARM_NUMBER), segment));
        if (this.module != null) predicates.add(criteriaBuilder.equal(root.get(MODULE_TYPE), module));
        if (this.cardType != null) predicates.add(criteriaBuilder.equal(root.get(CARD_TYPE), cardType));
        if (this.processType != null) predicates.add(criteriaBuilder.equal(root.get(PROCESS_TYPE), processType));
        if (this.rewardType != null) predicates.add(criteriaBuilder.equal(root.get(REWARD_TYPE), rewardType));
        if (this.min != null && this.max != null) predicates.add(criteriaBuilder.between(root.get(PARAMETER_NUM), min, max));

        return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
    }

}

推荐阅读