Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot Spring引导异常处理最佳实践_Spring Boot - Fatal编程技术网

Spring boot Spring引导异常处理最佳实践

Spring boot Spring引导异常处理最佳实践,spring-boot,Spring Boot,我有一个关于异常处理的简单问题。 我目前有一个分为多个层的应用程序:控制器、服务、存储库,我的问题是:异常处理应该由控制器还是由服务来完成 例如: 控制器: @PostMapping(value = "/{id}/parents", produces = "application/json; charset=utf-8") public ResponseEntity<AccommodationRequestDTO> resident(@Path

我有一个关于异常处理的简单问题。 我目前有一个分为多个层的应用程序:控制器、服务、存储库,我的问题是:异常处理应该由控制器还是由服务来完成

例如:

控制器:

@PostMapping(value = "/{id}/parents", produces = "application/json; charset=utf-8")
public ResponseEntity<AccommodationRequestDTO> resident(@PathVariable Long id, @Valid @RequestBody ParentsAndUrgencyContactDTO parentsAndUrgencyContactDTO) {
    AccommodationRequestDTO saved;
    try {
        saved = this.service.parents(id, parentsAndUrgencyContactDTO);
    } catch (Exception e) {
        throw new ResponseStatusException(
                HttpStatus.INTERNAL_SERVER_ERROR,
                "Failed to save request", e);
    }
    return ResponseEntity.ok(saved);
}
@PostMapping(value=“/{id}/parents”,products=“application/json;charset=utf-8”)
public ResponseEntity常驻(@path variable Long id,@Valid@RequestBody ParentsAndUrgencyContactDTO ParentsAndUrgencyContactDTO){
要保存的住宿请求;
试一试{
saved=this.service.parents(id、parents和urgency contactdto);
}捕获(例外e){
抛出新的ResponseStatusException(
HttpStatus.INTERNAL\u服务器\u错误,
“保存请求失败”,e);
}
返回ResponseEntity.ok(已保存);
}
服务:

public AccommodationRequestDTO parents(Long id, ParentsAndUrgencyContactDTO parentsAndUrgencyContactDTO) {
    Optional<AccommodationRequest> accommodationRequest = repository.findById(id);

    if (accommodationRequest.isPresent()) {
        AccommodationRequest saved = accommodationRequest.get();
        Parent firstParent = parentMapper.toEntity(parentsAndUrgencyContactDTO.getFirstParent());
        Parent secondParent = parentMapper.toEntity(parentsAndUrgencyContactDTO.getSecondParent());

        firstParent = parentRepository.save(firstParent);
        secondParent = parentRepository.save(secondParent);

        saved.setFirstParent(firstParent);
        saved.setSecondParent(secondParent);
        saved = this.repository.save(saved);

        return mapper.toDTO(saved);
    } else {
        throw new ResponseStatusException(
                HttpStatus.NOT_FOUND, " with id " + id + " not found !");
    }

}
向家长申请公共住宿(长id、家长和紧急联系电话、家长和紧急联系电话){
可选调节请求=repository.findById(id);
if(调节请求.isPresent()){
已保存的调节请求=调节请求.get();
Parent firstParent=parentMapper.toEntity(parentsAndUrgencyContactDTO.getFirstParent());
Parent secondParent=parentMapper.toEntity(parentsAndUrgencyContactDTO.getSecondParent());
firstParent=parentRepository.save(firstParent);
secondParent=parentRepository.save(secondParent);
已保存。setFirstParent(firstParent);
已保存。setSecondParent(第二父级);
保存=this.repository.save(已保存);
返回mapper.toDTO(已保存);
}否则{
抛出新的ResponseStatusException(
HttpStatus.NOT_FOUND,“id为“+id+”未找到!”);
}
}

最佳做法是什么?我是否应该从控制器中删除try catch并将其置于我的服务中?因为有了这段代码,我的404异常被控制器捕获覆盖。

是的,您需要转到服务。您可以通过创建扩展ResponseEntityExceptionHandler的类来处理异常。是的,您需要移动到服务。若要在服务层抛出异常,可以通过创建扩展ResponseEntityExceptionHandler的类来处理异常

最好再定义一个名为exception的包

并在其中包含自定义异常、异常响应和异常处理程序

我的代码结构如下所示:

package com.***.demo.exception;
公共类DataNotFound扩展EntityNotFoundException{
公共DataNotFound(字符串消息){
超级(信息);
}
}
package com.***.demo.exception;
@资料
@AllArgsConstructor
公共类错误详细信息{
私有日期时间戳;
私有字符串消息;
私有字符串详细信息;
}
package com.***.demo.exception;
@控制器建议
公共类MyExceptionHandler{
@ExceptionHandler(DataNotFound.class)
公共响应属性dataNotFoundExceptionHandling(异常异常、WebRequest请求){
返回新的ResponseEntity(新的ErrorDetails(新日期(),异常.getMessage(),请求.getDescription(false)),HttpStatus.BAD_请求);
}
@ExceptionHandler(Exception.class)
公共响应性globalExceptionHandling(异常异常、WebRequest请求){
返回新的ResponseEntity(新的ErrorDetails(新日期(),异常.getMessage(),请求.getDescription(false)),HttpStatus.INTERNAL_服务器_错误);
}
}

希望您得到答案。

如果您想抛出异常,请在服务层抛出它

最好再定义一个名为exception的包

并在其中包含自定义异常、异常响应和异常处理程序

我的代码结构如下所示:

package com.***.demo.exception;
公共类DataNotFound扩展EntityNotFoundException{
公共DataNotFound(字符串消息){
超级(信息);
}
}
package com.***.demo.exception;
@资料
@AllArgsConstructor
公共类错误详细信息{
私有日期时间戳;
私有字符串消息;
私有字符串详细信息;
}
package com.***.demo.exception;
@控制器建议
公共类MyExceptionHandler{
@ExceptionHandler(DataNotFound.class)
公共响应属性dataNotFoundExceptionHandling(异常异常、WebRequest请求){
返回新的ResponseEntity(新的ErrorDetails(新日期(),异常.getMessage(),请求.getDescription(false)),HttpStatus.BAD_请求);
}
@ExceptionHandler(Exception.class)
公共响应性globalExceptionHandling(异常异常、WebRequest请求){
返回新的ResponseEntity(新的ErrorDetails(新日期(),异常.getMessage(),请求.getDescription(false)),HttpStatus.INTERNAL_服务器_错误);
}
}

希望您能得到答案。

如果您不使用
@ControllerAdvice
,当异常类型决定您要在客户端上显示什么时,最佳做法是从您的服务中抛出一些内容,并在控制器上专门捕获它。因此,每个方法捕获每个特定的异常,并根据异常类型决定输出的内容。例如:当它为空指针时,输出为错误500;当它缺少请求时,输出为错误400,等等

除非异常是您需要通过业务逻辑来处理的,否则它应该在您的用例服务中被捕获

但如果您使用Spring(或任何具有异常处理程序的框架),我更喜欢使用
@ControllerAdvice
,因为您不再需要捕捉控制器上的每一件事情,只要在每个控制器方法上放置
抛出异常
,它就会被捕捉到
@ControllerAdvice
类上。因此,决定输出的任何逻辑都是全局基于该类的(或者您可以将其设置为仅来自某些类或仅来自某些包的句柄)和yo