Передача ошибок обратно в представление из сервисного уровня - PullRequest
8 голосов
/ 12 июля 2010

Редактировать: Я рассмотрел аннотацию @ExceptionHandler в Spring 3 и объединил ее с Вариант 1 ниже, выглядит довольно чистым решением.

См. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers

Я также нашел, что это хорошее чтение: http://blog.decaresystems.ie/index.php/2006/04/07/difficult-choices-in-handling-exceptions-in-enterprise-java-applications/


Я уже некоторое время занимаюсь разработкой с использованием среды Spring MVC, однако я изо всех сил пытаюсь найти «хороший» способ передачи ошибок, возникающих на уровне обслуживания, обратно в JSP.

По сути, я не верю, что бизнес-логика (кроме «это поле обязательно») должна присутствовать в Валидаторах, особенно любая логика, требующая доступа к БД. Итак, что я делал, так это помещал дальнейшую, более сложную проверку и бизнес-логику на уровень обслуживания.

Например, допустим, у меня есть страница, которая позволяет пользователю купить книгу. Они нажимают «Купить» на JSP, и контроллер вызывает службу, чтобы все это произошло ... Теперь, что произойдет, если служба обнаружит, что у них недостаточно средств - как мне вернуть это сообщение в JSP, так что приятно Сообщение «Недостаточно средств» может отображаться пользователю? Я рассмотрел два пути, и я не уверен, что является правильным ...

Вариант 1: Исключения

Первый способ, который я подумал, - вызвать исключение на уровне службы, перехватить его в контроллере и добавить сообщение в BindingResult.

Услуги:

public void pay(Book book) throws InsufficientFundsException {
    // Some logic goes here, which ends up throwing the above exception
}

Контроллер:

public ModelAndView(@ModelAttribute("book") Book book, BindingResult errors) {
    try {
        pay(book);
    } catch (InsufficientFundsException ex) {
        errors.reject("insufficient.funds");
    }
    return new ModelAndView(blahblahblah);
}

Вариант 2: Передать BindingResult на сервисный уровень

Второй способ состоял в том, чтобы передать объект BindingResult на сервисный уровень и вызвать дополнительные ошибки для него.

Услуги:

public void pay(Book book, BindingResult errors) {
    // User has insufficient funds, so...
    errors.reject("insufficient.funds);
}

Я вижу проблемы с обоими этими способами. Вариант 1 чувствует себя неловко, потому что я должен не только перехватить исключение, но и добавить ошибку к результату привязки, чтобы я чувствовал, что я делаю одно и то же дважды. А вариант 2, похоже, слишком тесно связывает сервисный уровень с контроллером.

Наконец , я понимаю, что есть SimpleMappingExceptionResolver, который можно использовать в сочетании с вариантом 1, но я не уверен, насколько он уместен (возможно, я не видел подходящего примера?) , В приведенном выше примере, давайте просто скажем, ради аргумента, что я бы хотел, чтобы пользователь вернулся в исходную форму с красной ошибкой над формой, а не с перенаправлением на совершенно другую страницу. SimpleMappingExceptionResolver представляется мне полезным, когда вы хотите перенаправить пользователя на стандартную страницу ошибки при возникновении определенного исключения (что не совсем то, что я хочу знать, как это сделать).

1 Ответ

4 голосов
/ 12 июля 2010

Java использует исключения, чтобы естественным образом обрабатывать подобные вещи.В конце концов, это, как правило, упрощает вашу логику и снижает вероятность ошибки, забывая проверить, что что-то было ошибочным.Вы также можете убрать логику ошибок из основного потока кода.

Я не понимаю, почему представленный вами случай отличается от любого другого случая, где я использовал бы обработку исключений для обработки ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...