Flo*_*opn 8 java rest spring spring-data spring-data-jpa
我正在为一个大学项目编写一个简单的库 API。我有一个包含书籍的数据库,每个数据库都有自己的 ID。我正在使用 Spring Boot 来制作服务。我有一个BookRepositorywhich extendsJpaRepository<Book, Long>和一个服务实现。
@Service
public class BookServiceImpl implements BookService{
@Autowired
private BookRepository bookRepository;
@Async
@Override
public void delete (Long id){
bookRepository.delete(id);
}
}
Run Code Online (Sandbox Code Playgroud)
稍后,REST 控制器处理请求:
@RestController
public class BookServiceController{
@Autowired
private BookService bookService;
@RequestMapping(value="books/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Book> deleteBook (@PathVariable("id") Long id){
bookService.delete(id);
return new ResponseEntity<Book>(HttpStatus.OK);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我要删除不在数据库中的 Book(例如 ID 为 123),则会抛出 EmptyResultDataAccessException。
我的问题是,我如何以及在哪里处理异常,以及如何避免以这种方式投射 NullPointerException?
提前致谢。
避免这种情况的最优雅的方法EmptyResultDataAccessException是在界面中定义一个特定的方法Repository来通过 id 字段删除。
假设您的 id 字段名为 bookId:
public interface BookRepository extends JpaRepository<Book, Long> {
Long deleteByBookId(Long bookId);
}
Run Code Online (Sandbox Code Playgroud)
这样就不会抛出异常。
如果您的 id 字段只是简单地称为 id,我还没有测试过该解决方案。
在操作的情况下DELETE,您不再真正返回实体;而是返回实体。您只是确认资源已消失。由于DELETE是幂等的(您可以多次删除记录),因此无论记录是否存在都可以返回相同的状态代码,如果找不到记录则返回 404。您还可以简化处理程序方法:
@DeleteMapping("/books/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT) // because you deleted it
public void deleteBook(@PathVariable Long id) {
try {
bookService.delete(id); // or just use the repository directly
} catch (EmptyResultDataAccessException ex) {
// either do nothing to return a 204, or
throw new NotFoundException();
}
}
Run Code Online (Sandbox Code Playgroud)
其中有一个指示状态的异常:
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {}
Run Code Online (Sandbox Code Playgroud)
似乎EmptyResultDataAccessException应该已经用状态注释NOT_FOUND; 这是一个潜在的增强请求。
| 归档时间: |
|
| 查看次数: |
6078 次 |
| 最近记录: |