【问题标题】:How to handle exceptions thrown in the service layer?如何处理服务层抛出的异常?
【发布时间】:2020-01-07 07:03:17
【问题描述】:

我正在开发一个 spring-boot 应用程序。我尝试处理异常。但我想我的处理方式有问题,因为它总是抛出内部服务器错误 500。

我尝试设置自定义异常类,并将响应状态代码与@ResponseStatus 一起使用。但无论异常是什么,它都只会引发内部服务器错误。 我正在使用 intellij,我在异常中给出的消息打印在那里,但响应正文为空。我想这一定是因为它引发了内部服务器错误。

控制器类

 @RequestMapping(value = "/attendance",method = RequestMethod.POST)
    public ResponseEntity<?> enterAttendance(@RequestBody ViewDTO viewDTO) throws CustomException{
        return new ResponseEntity<>(tempResultServices.handleAttendance(viewDTO),HttpStatus.OK);
    }
}


Service layer

    @Override
    public TempResult handleAttendance(ViewDTO viewDTO) throws CustomException {
        TempIdentity tempIdentity=new TempIdentity();
        tempIdentity.setRegistrationNo(viewDTO.getRegistrationNo());
        tempIdentity.setCourseId(viewDTO.getCourseId());
        tempIdentity.setYear(viewDTO.getYear());
        tempIdentity.setSemester(viewDTO.getSemester());

        User user=userService.findByUserId(viewDTO.getUserId());
        tempIdentity.setUser(user);

        if(!viewDTO.isAttendance()){
            TempResult tempResultUser =new TempResult(tempIdentity,viewDTO.isAttendance(),0);
            ResultIdentity resultIdentity=new ResultIdentity(tempIdentity.getRegistrationNo(),tempIdentity.getCourseId(),tempIdentity.getYear(),tempIdentity.getSemester());
            Result result=new Result(resultIdentity,0,"E*");

            AttendanceDraft attendanceDraft=atteDraftService.findDraft(viewDTO.getRegistrationNo(),viewDTO.getCourseId(),viewDTO.getYear(),viewDTO.getSemester(),viewDTO.getUserId());
            if(attendanceDraft!=null){
                attendanceDraft.setStatus(true);
                atteDraftService.save(attendanceDraft);
                //atteDraftService.delete(attendanceDraft);

                tempResultRepository.save(tempResultUser);
                resultRepository.save(result);

                return tempResultUser;
            }
            else{
                throw new CustomException("No draft available");
            }
        }
        else{
            TempResult tempResultUser =new TempResult(tempIdentity,viewDTO.isAttendance());



            AttendanceDraft attendanceDraft=atteDraftService.findDraft(viewDTO.getRegistrationNo(),viewDTO.getCourseId(),viewDTO.getYear(),viewDTO.getSemester(),viewDTO.getUserId());
            if(attendanceDraft!=null){
                attendanceDraft.setStatus(true);
                atteDraftService.save(attendanceDraft);
                //atteDraftService.delete(attendanceDraft);

                tempResultRepository.save(tempResultUser);

                return tempResultUser;
            }
            else{
                throw new CustomException("No draft available");
            }
        }
    }

The exception class

@ResponseStatus(code= HttpStatus.NOT_FOUND)
public class CustomException extends RuntimeException {
public CustomException(String message){
    super(message);
}

}

intellij 中的终端打印“没有可用的草稿”。但我不希望它作为内部服务器错误。 谁能告诉我应该如何处理这些错误?

我尝试使用@RestControllerAdvice

@RestControllerAdvice
public class WebRestControllerAdvice {

    @ExceptionHandler(CustomException.class)
    public ResponseMsg handleNotFoundException(CustomException ex) {
        ResponseMsg responseMsg = new ResponseMsg(ex.getMessage());
        return responseMsg;
    }

}

这是我的响应消息类

public class ResponseMsg {

    private String message;
//getters and setters
}

这是应用程序中的另一个简单请求

 @RequestMapping(value = "/user/view",method = RequestMethod.POST)
    public ResponseEntity<?> getUser(@RequestBody UserDTO userDTO) throws CustomException{
        User user=userService.findByUsername(userDTO.getUsername());
        if(user!=null){
            return ResponseEntity.ok(user);
        }
//
        throw new CustomException("User not found");
    }

但仍然没有抛出自定义异常。响应正文为空。但 intellij 说“找不到用户”,邮递员返回状态码 500。

【问题讨论】:

  • 如果你不想要Internal Server Error,那么就不要在else块中使用throw new CustomException("No draft available");。只需将其记录为消息即可。
  • 如果要将异常映射到响应代码,则需要使用 @ControllerAdvice 注释类 baeldung.com/exception-handling-for-rest-with-spring 从自定义异常映射您想要的响应代码
  • 你能给我一个链接到一个好的和清晰的例子吗?我真的很困惑。

标签: spring-boot exception


【解决方案1】:

Spring boot 有一种非常方便的方式来处理应用程序中定义 @ControllerAdvice bean 的任何层中的异常。然后你可以在你的代码中抛出任何类型的异常,它会被这个类“捕获”。

在此之后,您可以处理并返回您的应用需要返回的任何内容。 顺便说一句,您可以返回您的自定义对象,它会自动解析为 json。

文档:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/

示例代码:

@ControllerAdvice
public class ErrorHandler {

@ExceptionHandler(BadRequestException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public Object processValidationError(BadRequestException ex) {
    //return whatever you need to return in your API
}

}

【讨论】:

  • 我也尝试过这种方式,但似乎没有任何效果。
  • 您必须显示所有代码才能为您提供帮助。这应该有效,在“@ExceptionHandler”上应该去 CustomException.class 和在“@ResponseStatus”上你想要的状态。还将您“@ControllerAdvice”放在 Spring 可见的包上……这样它就可以扫描它。 (通常在你的主课旁边应该可以)。
  • 我用上面的方式尝试使用restController,是不是错了?
  • 在您的方法“handleNotFoundException”中您缺少http状态代码,请查看我的答案(您需要使用@ResponseStatus)。如果在此之后工作,请将答案标记为已接受。
  • 不,即使使用了@ResponseStatus 还是一样
猜你喜欢
  • 2022-10-13
  • 2015-06-06
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-11
  • 1970-01-01
相关资源
最近更新 更多