簡體   English   中英

我應該在模型中使用HttpStatus拋出異常嗎?

[英]Should I throw exception with HttpStatus in model?

假設我開發了一些休息api。 我有web層(控制器)和服務層(模型)。 在服務層中使用HttpStatus代碼拋出異常是一種好習慣嗎?

有人會說,該模型不應該對Web層有任何了解,它不應該依賴於Web層。

但是,讓我們考慮一下這種情況:

在控制器中使用HttpStatus拋出異常

---服務---

 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客戶端的正確響應? 此外,我可以忘記捕獲一些可以正確報告的異常,它將作為默認的內部服務器異常返回。 在控制器中,我總是應該查看服務層並檢查哪些異常可以使服務正確處理它們。 (請不要在java中建議檢查異常)。

現在讓我們看看另一個解決方案:

在服務層(模型)中使用HttpStatus拋出異常

---服務---

class userService {

   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);         
  }       
}

就是這樣。 更少的代碼。 現在我不必處理可能拋出Service層的每個可能的異常,每次編寫控制器時我都不必手動檢查服務異常,我不會忘記處理一些異常(因為它們在服務層中正確形成)這不容易出錯。

再次, 這是在服務層處理Http相關數據的不良做法嗎?

如果它不好,你將如何處理我描述的issus。

謝謝。

PS:在這兩種解決方案中,一些通用的ErrorHandler捕獲異常並使用適當的狀態代碼形成響應。

您可以在Controller內部的方法中使用@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-handling-in-spring-mvc

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM