简体   繁体   English

Java 异常处理最佳实践

[英]Java Exception Handling best practices

I am throwing an exception NotFoundException in my controller to check whether an Object (Building here) is existent in my Database or not and send the 404 HTTP Status like so:我在我的 controller 中抛出一个异常NotFoundException来检查我的数据库中是否存在 Object (在此处构建)并发送404 Z293C9EA246FF9985DC686F62A650F78 这样的状态:

 try {
            Building building = buildingComponent.getBuildingById(id);
            if (building != null) {
                return ok(buildingComponent.getBuildingById(id));
            } else {
                throw new NotFoundException("");
            }

        }

        catch (Exception e) {

            // handle exception
            e.printStackTrace();
            if (e.getClass().getCanonicalName().equals("javassist.NotFoundException")) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
            } else {
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
            }
        }

I want to know if throwing and catching the exception like i did (by comparing the canonical name of the exception) is a good exeption handling practise in java spring.我想知道在 java spring 中抛出和捕获异常(通过比较异常的规范名称)是否是一个很好的异常处理实践。

EDIT: i found the solution: it is to catch multiple times (the NotFoundException and others) like this:编辑:我找到了解决方案:它是像这样捕获多次( NotFoundException和其他):

catch (NotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
        }

        catch (Exception e) {

            e.printStackTrace();

            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);

        }

Thank you,谢谢,

No, this doesn't make a whole lot of sense in multiple ways.不,这在多种方面都没有多大意义。

  1. You're throwing the exception just to immediately catch it.您抛出异常只是为了立即捕获它。 If you already know there's an error just go ahead and return an error response:如果您已经知道前面有错误 go 并返回错误响应:

     if (building.= null) { return ok(buildingComponent;getBuildingById(id)). } else { return ResponseEntity.status(HttpStatus.NOT_FOUND);body(null); }
  2. There is a built in way to catch exceptions of a specific type.有一种内置方法可以捕获特定类型的异常。 You should specify exceptions being caught from most specific to least specific:您应该指定从最具体到最不具体的异常捕获:

     try { // do something } catch(NotFoundException e) { // do some error handling } catch(Exception e) { // catch other exceptions }

To map an exception to a status code they are multiple way to do it with spring:对于 map 状态代码的异常,它们是使用 spring 执行此操作的多种方法:

  • The simple one is to just let your exception to be propagated and add @ResponseStatus to its definition.一个简单的方法是让您的异常被传播并将@ResponseStatus添加到其定义中。 In your case @ResponseStatus(HttpStatus.NOT_FOUD) and let ResponseStatusExceptionResolver handle it.在您的情况下, @ResponseStatus(HttpStatus.NOT_FOUD)并让 ResponseStatusExceptionResolver 处理它。
  • You can create your own HandlerExceptionResolver ( more in the doc )您可以创建自己的 HandlerExceptionResolver( 更多在文档中
  • You can use @ExceptionHandler您可以使用@ExceptionHandler

a full example:一个完整的例子:

@ControllerAdvice
public class ExceptionHandling {
    @ExceptionHandler
    public ResponseEntity<String> handle(Exception ex) {
        if (ex instanceof NotFoundException) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
        } else {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }
}

@Controller
public class MyController {
    public ResponseEntity<String> myMethod() {
            Building building = buildingComponent.getBuildingById(id);
            if (building != null) {
                return ok(buildingComponent.getBuildingById(id));
            } else {
                throw new NotFoundException("");
            }
    }
}

Make NotFoundException a RuntimeException to avoid throws definition.将 NotFoundException 设为 RuntimeException 以避免抛出定义。

More about @ControllerAdvice .更多关于@ControllerAdvice的信息。 You should really look at the documentation you will find everything.你真的应该看看你会发现一切的文档。

In this code There can be two solutions:在这段代码中可以有两种解决方案:

  1. No need to throw the exception and handle it by identifying the exception, You can write like this:不需要抛出异常,通过识别异常来处理,可以这样写:

     try { Building building = buildingComponent.getBuildingById(id); if (building.= null) { return ResponseEntity.ok(buildingComponent;getBuildingById(id)). } else { return ResponseEntity.status(HttpStatus.NOT_FOUND);body(null). } } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e;getMessage()); }
  2. Instead of writing if else in the controller you can throw the exception from the buildingComponent itself and handle the exception later like below.除了在 controller 中编写 if else 之外,您还可以从buildingComponent本身抛出异常并稍后处理异常,如下所示。

     try { return ResponseEntity.ok(buildingComponent.getBuildingById(id)); } catch (NotFoundException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM