2015-11-27 1 views
3

Скажем, я развиваю некоторый отдых api. У меня есть веб-уровень (контроллеры) и уровень обслуживания (модель). Является ли хорошей практикой бросать исключение с кодом HttpStatus в уровень обслуживания?Должен ли я исключать исключение из HttpStatus в модели?

Кто-то скажет, что эта модель не должна знать ничего о веб-слое, она не должна зависеть от веб-уровня.

Но, давайте рассмотрим эту ситуацию:

выбрасывающие исключений с 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 в Service Layer (модель)

--- Сервис ---

класс 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);   
    }  
} 

И все. Меньше кода. Теперь мне не нужно обрабатывать каждое возможное исключение, которое может вызвать сервисный уровень. Мне не нужно каждый раз проверять служебные исключения каждый раз, когда я пишу контроллер, и я не забуду обработать какое-то исключение (потому что они правильно сформированы в слое сервиса) и это менее подвержено ошибкам.

И снова - это плохая практика для обработки данных, связанных с Http, в сервисном слое?

Если это плохо, как вы справитесь с issus, который я описал.

спасибо.

P.S .: В обоих решениях некоторый общий ErrorHandler обнаруживает исключения и формирует ответ с соответствующими кодами состояния.

ответ

3

Вы можете использовать @ExceptionHandler в методе внутри контроллера для управления исключением в том же контроллере

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

или вы можете создать класс с @ControllerAdvice управлять ошибками от всех Yours контроллеров

@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

+0

также см [Спринг Ссылка] (http://docs.spring.io/spring/docs/4.2.4.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#mvc-exceptionhandlers) –