如何解决ConstraintValidator - 用于缺失数据
我有调用 Web 服务的客户端代码来获取某个日期范围内的每月价格,然后返回平均年价格:
@Service
@RequiredArgsConstructor
@Slf4j
public class PriceAverageService {
private final PriceServiceClient priceServiceClient ;
public BigDecimal getAverageAnnualPrice(Long productId,LocalDate startDate,LocalDate endDate) {
List<Price> prices = priceServiceClient.getMonthlyPrices(productId,startDate,endDate);
// code to compute average annual price
return averageMonthlyPrice;
}
}
@FeignClient(name="price-service")
@Validated
public interface PriceServiceClient {
@GetMapping("/product/price")
@Valid
@ConsecutivePrices
List<Price> getMonthlyPrices(
@RequestParam(name="productId")
Long productId,@RequestParam(name="startDate")
@DateTimeFormat(iso=DateTimeFormat.ISO.DATE)
LocalDate startDate,@RequestParam(name="endDate")
@DateTimeFormat(iso=DateTimeFormat.ISO.DATE)
LocalDate endDate);
}
Price
类:
@Value
public class Price {
BigDecimal price;
LocalDate priceDate;
}
如果相邻月份没有缺少价格的月份缺少价格,则这是错误的。例如,以下价格数据是错误的:2020 年 1 月 15.00 美元、2020 年 3 月 20.00 美元。那是因为缺少 2020 年 2 月。 @ConsecutivePrices
是检查此条件的 ConstraintValidator
。
我还需要检查 startDate
和 endDate
是否有价格。如果缺少任何一个,则不是错误。如果缺少其中一个,代码应为 getAverageAnnualPrice
返回 null(而不是计算平均年价格)。
是否应该使用 ConstraintValidator
来检查 startDate
和 endDate
价格是否存在?如果是这样,我会在 MethodArgumentNotValidException
内捕获 getAverageAnnualPrice
吗?
解决方法
我不会使用 ConstraintValidator 来实现您服务的域逻辑的一部分。正如您所说,缺少开始/结束日期价格不是错误,而是应该由您的服务妥善处理的预期情况。 (通常,我会尽量避免在正常/快乐情况下使用异常。这包括使用 ConstraintValidators。)
相比之下,在您的域模型中缺少连续价格没有意义(根据您的解释),即调用的服务不应返回此值,除非发生了真正意想不到的事情(例如损坏的数据模型)。因此,在这种情况下,验证器(并抛出异常)可能是合适的。如果不满足该条件(即,如果有时返回丢失的连续价格可能是正常的,例如因为产品暂时停售或类似的情况),那么即使在这种情况下,我也会重新考虑使用 ConstraintValidator .
(免责声明:我不是 Spring 用户,作为 Java 用户,我从未在客户端界面中使用过约束验证器,所以我可能会遗漏一些东西。但是我认为这些考虑因素相当普遍。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。