2015-11-03 78 views
2

比方說,我有以下運行時異常:哪裏扔HTTP運行時異常

@ResponseStatus(HttpStatus.EXPECTATION_FAILED) 
public class ExpectationsFailedException extends RuntimeException { 
    public ExpectationsFailedException(String message) { 
     super(message); 
    } 
} 

我的問題是,如果它是確定扔前面的HTTP例外,在我服務層或者我應該把它從我的控制器:

@Service 
public class UserService { 

    @Autowired 
    ... 

    public void addUser(final String email, final String username, final String password){ 
     if(parameters_are_not_valid){ 
      throw new ExpectationsFailedException("Invalid input"); 
     } 
    } 

} 

控制器異常拋出的解決方案將是以下:

@Service 
public class UserService { 

    @Autowired 
    ... 

    public void addUser(final String email, final String username, final String password) throws InvalidInputParameters { 
     if(parameters_are_not_valid){ 
      throw new InvalidInputParameters("Invalid input"); 
     } 
    } 

} 

和我的控制器中

@RestController 
public class XController{ 

    @Autowired 
    private UserService userService; 

    @RequestMapping(value = "/addUser", method = RequestMethod.POST) 
    public void addUser(@Valid @RequestBody SignUpForm form, BindingResult bindingResult){ 
     if(bindingResult.hasErrors()){ 
      throw new ExpectationsFailedException("Input parameters conditions were not fulfilled"); 
     } 

     try { 
      userService.addUser(...); 
     } 
     catch(InvalidInputParameters ex){ 
      throw new ExpectationsFailedException("Invalid service input parameters"); 
     } 
    } 
} 

哪種解決方案是首選?爲什麼?我有一種感覺,我不應該在我的服務中拋出HTTP異常,因爲我可能會在可能與HTTP無關的其他上下文中使用該服務。

我會去第二個。

您認爲如何?

回答

2

我同意你最後的聲明。您的服務層應該獨立於HTTP或frontent框架(@ResponseStatus是Spring MVC註釋,因此它不是在您的服務層中使用它的最佳實踐)。

但是,您不必在服務層中拋出一個異常,將其捕獲到控制器中,然後重新拋出另一個異常,並註釋@ResponseStatus。只需爲服務異常添加異常處理程序並從中返回適當的響應狀態。你有大量的選項,例如@ExceptionHandler

@ResponseStatus(HttpStatus.EXPECTATION_FAILED) 
@ExceptionHandler(InvalidInputParameters.class) 
public void handle() { 
    // Do nothing, just return the status 
} 

你可以把這個代碼@ControllerAdvice註解類,使之爲所有控制器或只是在你控制器如果不是其他地方需要用到它。