我有一个使用 Hibernate 和 Spring Data JPA 的 Spring 应用程序
CrudRepository
。如果查询的数据存在于数据库中,则一切似乎都可以正常工作。但是,如果有一个查询没有返回结果,则 CrudRepository
返回 null
,我会得到 NullPointerException
。例如,如果数据库中有 id 为 3 的行,那么它就可以正常工作。如果没有 id 为 3 的行,则会失败并显示:出现意外错误(类型=内部服务器错误, 状态=500)
在客户端,
http://localhost:8080/api/id=3
在服务器端。
处理“无结果”查询的简单情况的正确方法是什么?
NullPointerException
,则返回它的一些表示形式作为
null
响应。否则,返回 200 OK
。最后,你将拥有一个像这样的控制器:404 Not Found
您可以重构前面的代码以合并 Java 8 的
@RequestMapping(...)
public ResponseEntity<?> getOne(...) {
Something something = repository.findOne(...);
if (something == null)
return ResponseEntity.notFound().build();
return ResponseEntity.ok(something);
}
评论中提到的JB Nizet。基本上,
Optional<T>
只是一个容器,可能会也可能不会容纳Optional<T>
类型的值。您可以使用此类型作为 Spring Data JPA 方法的返回类型,如下所示:
T
然后为
public interface SomethingRepository extends CrudRepository<Something, Long> {
Optional<Something> findById(Long id);
}
定义一个例外:
404 Not Found
如果您在控制器中抛出
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {}
类型的异常,Spring MVC 的异常解析器将捕获该异常并将其转换为
NotFoundException
HTTP 响应。最后你的控制器会是这样的:
404 Not Found
更详细的讨论:
Spring Data JPA 的
@RequestMapping(...)
public Something getOne(...) {
return repository.findById(id).orElseThrow(NotFoundException::new);
}
阅读此处。 Spring MVC 的异常解析器,
Optional<T>
阅读此处。 REST 最佳实践,您可以查看《REST 实践》一书。
Optional<T>