当前位置: 首页 > 知识库问答 >
问题:

我是否应该在模型中抛出带有HttpStatus的异常?

傅博容
2023-03-14
 class userService {

       public void updateUser(int userId, String username, String email) {

           if ( //userid not found) {
               throw new UserNotFoundException("User not found");
           }

           if ( // bad email format) {
               throw new BadArgumentException("Bad email format");
           } 

           if ( // user is not active) {
               throw new AccessDeniedException("User is not active"); 
           }     

           ... here save user ... 

       }
    }
class UserController {

  @RequestMapping ....
  public void updateUser(int id, String username, String email) {
     try{
        userService.updateUser(id, username, email);
     }
     catch (UserNotFoundException e) {
       throw new HttpException(e.getMessage(), HttpStatus.NOT_FOUND);
     } 
     catch (BadArgumentExceptione e) {
       throw new HttpException(e.getMessage(), HttpStatus.BAD_REQUEST);
     }
     catch (AccessDeniedException e) {
        throw new HttpException(e.getMessage(), HttpStatus.FORBIDEN); 
     }         
  } 
}

你看?我应该编写多少额外的代码来向Api客户端返回正确的响应?此外,我可以忘记捕获一些可以正确报告的异常,它将作为默认的内部服务器异常返回。在controller中,我总是应该查看服务层,并检查哪些异常可以引发服务以正确处理它们。(请不要建议在java中检查异常)。

现在让我们来看看另一种解决方案:

在服务层(模型)中使用HttpStatus引发异常

   public void updateUser(int userId, String username, String email) {

       if ( //userid not found) {
           throw new UserNotFoundException("User not found", HttpStatus.NOT_FOUND);
       }

       if ( // bad email format) {
           throw new BadArgumentException("Bad email format", HttpStatus.BAD_REQUEST);
       } 

       if ( // user is not active) {
           throw new AccessDeniedException("User is not active", HTTP_STATUS.FORBIDEN); 
       }     

       ... here save user ... 

   }
}
class UserController {

  @RequestMapping ....
  public void updateUser(int id, String username, String email) {
     userService.updateUser(id, username, email);         
  }       
}

就这样了。代码更少。现在我不必处理每一个可能引发服务层的异常,我不必每次在编写控制器时手动检查服务异常,我也不会忘记处理一些异常(因为它们在服务层中正确形成),这样就不容易出错了。

同样,在服务层中处理Http相关数据的做法是不好的吗?

如果它是坏的,你将如何处理我描述的伊索斯。

共有1个答案

尹晟
2023-03-14

您可以在控制器内的方法中使用@ExceptionHandler来管理同一控制器中的异常

 @ExceptionHandler({MyException.class,OtherException.class})
  public String myMethodExceptionHandler() {...}

也可以使用@ControllerAdvice创建一个类来管理所有控制器的错误

@ControllerAdvice
class GlobalControllerExceptionHandler {
    @ResponseStatus(HttpStatus.CONFLICT)  // 409
    @ExceptionHandler(MyException.class)
    public void handleConflict() {
        // Nothing to do
    }
}

这里有一个教程。https://spring.io/blog/2013/11/01/exception-handing-in-spring-mvc

 类似资料:
  • 问题内容: 我正在编写一个JavaScript函数,该函数发出HTTP请求并返回对结果的承诺(但该问题同样适用于基于回调的实现)。 如果我立即知道为该函数提供的参数无效,该函数应该同步还是应该返回被拒绝的Promise(或者,如果您愿意,请使用实例调用回调)? 异步功能应 始终 以异步方式运行(特别是对于错误情况)有多重要?是否确定,如果你知道程序是不是一个合适的状态的异步操作继续进行? 例如:

  • 问题内容: 该方法中类抛出2 :和,但在我的书上面的代码捕获和。 为什么代码会捕获但没有捕获? 如果在线文档的Formatter类format()方法中甚至没有声明它,我们如何知道是否需要捕获? 问题答案: 文献:是一个 可以由不同类的在Java中像迭代器,枚举,被抛出 扫描仪 或StringTokenizer的。 在你的情况是。它不是从方法。 这 仅仅是在安全方面(如果不给下一个输入,然后抛出此

  • 我让我的程序工作并全部完成(java)。这是一个简短而简单的工作面试程序。我通过抛出自定义异常来处理诸如不正确的输入格式之类的事情。这是最好的方法还是我应该只做一个打印声明?

  • 问题内容: 考虑以下代码: 无需添加方法签名即可编译该代码。(它与同样表现到位,太)。 我理解为什么 可以 安全地运行它,因为实际上不能将其引发在块中,因此不能引发已检查的异常。我有兴趣知道在何处指定此行为。 并非永远都不会达到目标:以下代码也会编译: 但是,如果抛出一个检查的异常,它不会像我期望的那样编译: 在JLS Sec 11.2.2中 ,它说: 一,其抛出的表达式语句(§14.18)具有静

  • 我知道一种方法是: 有什么更干净的方法吗?(可能使用JUnit的?)

  • 我在Quarkus REST应用程序中有几个接受ID的调用。 我使用活动记录模式来处理数据库请求。来自Spring的将在结果集为空时抛出异常。我将使用捕获此异常,并抛出相应的响应代码(在本例中为404)。这也适用于所有其他例外情况。 有没有办法将Panache/Hibernate配置为在空结果集上抛出异常?现在,我必须手动检查结果是否为空/空,然后抛出相应的异常。 例如,这就是我现在要做的: 当我