Передача ошибок обратно в представление из сервисного уровня
Редактировать: я смотрел на весну 3 @ExceptionHandler
аннотация и объединение этого с вариантом 1 ниже выглядит довольно чистым решением.
См. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html.
Я также нашел это, чтобы быть хорошим чтением: 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 ответ
Java использует исключения для естественной обработки такого рода вещей. В конце концов, это, как правило, упрощает вашу логику и снижает вероятность ошибки, забывая проверить, что что-то было ошибочным. Вы также можете удалить логику ошибок из основного потока кода.
Я не понимаю, почему представленный вами случай отличается от любого другого случая, в котором я бы использовал обработку исключений для устранения ошибок.