2015-11-03 74 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注解类,使之为所有控制器或只是在你控制器如果不是其他地方需要用到它。