我有两条路径:
/students
/students/{id}/addresses
...具有以下行为:
POST
至/students
-201 Created
(如果成功创建了学生)POST
至/students/{id}/addresses
-201 Created
(如果在请求的用户下成功创建了地址)现在,假设客户POST
到/students/12/addresses
的情况,但没有id = 12的学生。
我应该如何处理这种情况?
我应该不加检查地插入并等待Hibernate抛出异常,还是应该在插入之前检查Student的存在性?
第一个选项:
StudentController.java
@Autowired
private AddressService addressService;
@PostMapping("/students/{id}/addresses")
public ResponseEntity<?> handleRequestOfCreateAddressToStudent(@PathVariable("id") Long studentId, @RequestBody Address address) {
address.setStudent(new Student(studentId));
Address createdAddress = addressService.saveAddress(address);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").build(createdAddress.getId());
return ResponseEntity.created(location).build();
}
AddressService.java
@Autowired
private AddressRepository addressRepository;
public Address saveAddress(Address address) {
// omitted for brevity...
return addressRepository.save(address);
}
这样,由于我使用的是Spring,因此应用程序将抛出DataIntegrityViolationException
,因为违反了约束(不存在具有此类ID的Student与该地址绑定)。而且,由于我需要将响应发送给客户端,因此我必须转换抛出的异常。
第二个选项:
StudentController.java
@Autowired
private StudentService studentService;
@Autowired
private AddressService addressService;
@PostMapping("/students/{id}/addresses")
public ResponseEntity<?> handleRequestOfCreateAddressToStudent(@PathVariable("id") Long studentId, @RequestBody Address address) throws StudentNotFoundException {
Student student = studentService.findById(studentId);
if(student == null)
throw new StudentNotFoundException("message");
address.setStudent(new Student(studentId));
Address createdAddress = addressService.saveAddress(address);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").build(createdAddress.getId());
return ResponseEntity.created(location).build();
}
这样,我不需要翻译异常,因为我已经知道Student不存在,因此我可以抛出自定义异常。
我在两种方法中的想法:
哪种方法是解决此问题的最佳方法?
我应该等待DAO抛出异常,还是应该通过检查Student是否存在来防止抛出异常?
答案 0 :(得分:0)
您对您的2个结论是正确的,但我想再添加一件事供您考虑。第二种选择对您来说是一个不错的选择, 只有在遇到这种情况时您要执行一些特定的操作。如果您只是要像记录所有其他错误一样记录一条错误消息,那么将这种特殊情况与其他情况区分开来就是没有意义的。
这就是说:如果您的业务逻辑中没有针对此类事件的特殊处理,则转到选项1。否则-选项2。