java - 这是一个多余的 NullPointerException 捕获吗?
问题描述
下面的 Spring REST 代码返回给定ticketId 的列表。
可以NullPointerException
在这段代码中抛出一个吗?
NullPointerException
明确陷入TicketController
:
catch (NullPointerException nullPointerException) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, nullPointerException.getMessage(), nullPointerException);
}
在检查票证 ID 是否为 null 时,可能会有这样的想法:
if (ticketId == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ticket id cannot be null");
}
期望 aNullPointerException
会被抛出,而不是 aResponseStatusException
被抛出?
如果变量ticketId
是路径参数,则它永远不能为空,因为在/
没有ticketId
我收到的情况下点击基本 url:
There was an unexpected error (type=Method Not Allowed, status=405).
全部来源:
@RestController
public class TicketController {
private final TicketServiceImpl ticketServiceImpl;
public TicketController(TicketServiceImpl ticketServiceImpl) {
this.ticketServiceImpl = ticketServiceImpl;
}
@GetMapping(path = "/{ticketId}")
public ResponseEntity<List<TicketResponse>> getTicketsById(
@PathVariable("ticketId") final Long ticketId) {
try {
final List<TicketResponse> ticketsById = ticketServiceImpl.getAll(ticketId);
return new ResponseEntity<>(ticketsById, HttpStatus.OK);
}
catch (NullPointerException nullPointerException) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, nullPointerException.getMessage(), nullPointerException);
}
catch (TicketNotFoundException ticketNotFoundException) {
throw new ResponseStatusException(
HttpStatus.NOT_FOUND, "Ticket id not found",
ticketNotFoundException);
}
}
}
@Service
public class TicketServiceImpl implements TicketService {
private final TicketRepository ticketRepository;
public TicketServiceImpl(TicketRepository ticketRepository) {
this.ticketRepository = ticketRepository;
}
@Override
public List<TicketResponse> getAll(Long ticketId) {
final List<TicketResponse> ticketResponselist = ticketRepository.findData(ticketId);
if (ticketId == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ticket id cannot be null");
}
else if (ticketResponselist.size() == 0) {
throw new TicketNotFoundException("ticket not found");
}
else {
return ticketResponselist;
}
}
}
@Repository
public interface TicketRepository {
public List<TicketResponse> findData(Long ticketId);
}
解决方案
if (ticketId == null)
检查应该在调用ticketRepository.findData(ticketId);
之前进行。
否则,验证没有意义。
另外,作为旁注,捕捉NullPointerException
是一种不好的做法。原因是抛出空指针异常主要是编码气味的标志。通过使用例如Optional或在方法级别进行适当的验证,代码应该是 null 安全的。在这种情况下,它将处于路由级别(即外部输入)。从那时起,如果设置了验证,您将处理不可为空的 id。
这也与从方法返回 null 有关,这也是一种不好的做法,因为它需要检查每个方法,然后使用返回的值。这会污染代码,引入新的抽象级别,并且通常会导致严重的错误。
推荐阅读
- azure-powershell - 如何使用 PowerShell 将 Azure 数据工厂诊断设置更改为“资源特定”表
- azure - 用于排除定义时间的 Azure Function Cron 表达式
- python - 有没有办法在 QDockWidget 上为 QStatusBar 设置按钮?
- laravel-8 - 函数 Livewire\LivewireManager::mount() 的参数太少,传入 0
- python - 使用 MatplotLib 直方图可视化第三个变量
- reactjs - 在没有依赖关系的情况下使用 useCallback 可以吗?
- python - 尝试将字典数据加载到数据框中时出错
- python - 具有通用键和 Callable[T] 值的 Python 字典
- javascript - 在字符串中换行后,我需要整个代码和项目符号的css动画。还需要控制循环时间
- javascript - 如何避免为 hasPendingWrites = true 触发 Firestore onSnapshot 更新?