Передача ошибок обратно в представление из сервисного уровня

Редактировать: я смотрел на весну 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 использует исключения для естественной обработки такого рода вещей. В конце концов, это, как правило, упрощает вашу логику и снижает вероятность ошибки, забывая проверить, что что-то было ошибочным. Вы также можете удалить логику ошибок из основного потока кода.

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

Другие вопросы по тегам