java - 可选 vs 异常,控制器 vs 服务
问题描述
我有 JAVA 设计注意事项:我在选择之间苦苦挣扎:
- 服务返回可选值和控制器处理不存在的情况
- 服务直接处理不存在的情况,如果存在则返回真实对象,如果不存在则抛出异常
是否有好的做法可以帮助我在这两种方法之间进行选择?
例如。 选项 1 控制器:
public ResponseEntity<Product> findProductById(@PathVariable Long productId) {
return this.productService.getProductById(productId).map(
p -> ResponseEntity.ok(p)
).orElseThrow(() -> new ResourceNotFoundException(ResourceType.PRODUCT, "Id", productId.toString()));
}
服务:
public Optional<Product> getProductById(Long id) {
return productRepository.findById(id).map(
product -> someLogic(product)
);
}
选项 2: 控制器
public ResponseEntity<Product> findProductById(@PathVariable Long productId) {
return ResponseEntity.ok(productService.getProductById(productId));
}
服务
public Product getProductById(Long id) {
return productRepository.findById(id).map(
product -> lazyLoadProduct(product)
).orElseThrow(() -> new ResourceNotFoundException(ResourceType.PRODUCT, "Id", id.toString()));;
}
对于这两种方法,我都有一个 ControllerAdvice,它最终会将此异常转换为相应的最终用户友好消息。所以他们都“工作相同”
解决方案
仅当出现需要与核心业务逻辑分开处理的意外事件或情况时,才应抛出异常。在搜索资源时,未找到该资源的事件是预期结果,因此并非例外。
因此,我认为您不应该使用这两种方法,而是对控制器进行编码,以便能够处理“未找到”响应的返回值。(这是一个空列表、特殊对象类型,还是仅仅null
取决于您的实现最容易支持的类型。)
推荐阅读
- flutter - how to map database keys to Strings & display the text assigned to each key on UI screen?
- python - Python: changing decimals into integer from a text file and adding value in empty column
- selenium - how to take screen shot using selenium WebDriver on Heroku
- reactjs - Electron: How to store data in cache manually
- java - Java:从特定字符'#'中提取字符串并将其分成数组
- mulesoft - 使用 Raml 验证标头
- python - 异或字节串
- javascript - Google 地址自动填充 - 更改字段 ID
- java - Java 将 DateTime 从“yyyy-MM-dd HH:mm:ss.SSSSSSS”转换为“yyyy-MM-dd HH:mm:ss.S”或从“yyyy-MM-dd HH:mm:ss.SSSSSSS”转换为“yyyy-MM-dd HH:mm:ss.SSS”
- ios - 快速提高以 .wav 格式录制的音频质量