Обработка исключений в веб-приложении Java
Я разрабатываю веб-приложение Java среднего размера со Struts в качестве структуры MVC и простой JDBC на уровне доступа к данным. Я искал лучшие практики обработки исключений в таком приложении. Я нашел несколько статей, некоторые из которых противоречат друг другу, только меня более смущали, а не делали все ясными и простыми. Некоторые говорят, что лучше использовать существующие исключения вместо определения особых случаев для приложений, а другие представляют собой огромную иерархию исключений приложения для каждой незначительной проблемы, которая может возникнуть в системе. Некоторые говорят, что лучше не обрабатывать исключения на уровне доступа к данным и делегировать их на уровень обслуживания, другие говорят, что исключения уровня доступа к данным должны быть локализованы локально, поскольку делегирование их на Service Layer нарушит абстракцию между этими двумя уровнями. И так далее.
Я был бы очень признателен, если бы вы сообщили мне о ссылках/именах к статьям/книгам, в которых представлены твердые решения, которые сработали для вас в таком сценарии. Решение должно прояснить по крайней мере следующие моменты с обоснованиями:
- Где будут обнаружены SQLExceptions?
- Где должны регистрироваться исключения?
- Должны ли регистрироваться исключения, отмеченные флажком?
- Следует ли исключить исключения из исключения на уровне презентации, и должны ли они отображаться пользователю?
- Как обрабатываются проверенные исключения, какие из них должны отображаться пользователю и как?
- Как использовать глобальную страницу обработчика исключений?
- Как следует использовать в этом контексте ActionErrors?
Спасибо
Ответы
Ответ 1
1: Где пойманы SQLExceptions?
В классах DAO на уровне доступа к данным. Вы можете в случае необходимости обернуть его с помощью специального исключения DAO. Это исключение DAO, в свою очередь, должно быть обработано дополнительно как проверенное исключение.
2: Где должны регистрироваться исключения?
В тот момент, когда вы собираетесь throw
их или пройти через среду обмена сообщениями.
3: Должны ли регистрироваться исключения, отмеченные флажком?
Они обязательно должны быть зарегистрированы. Они должны быть не встречаться в реальном мире, потому что это признак ошибки в логике кода (т.е. Ошибки разработчика), которая должна быть исправлена как ошибка. Они должны быть брошены до контейнера и позволяют контейнеру обрабатывать их с помощью <error-page>
в web.xml
. Чтобы зарегистрировать (и, в конечном итоге, отправить) их, используйте Filter
, который прослушивает страницу с ошибкой.
4: Должны ли исключенные исключения быть пойманы на уровне презентации и должны ли они отображаться пользователю?
Они не должны встречаться вообще.
5: Как обрабатываются проверенные исключения, какие из них должны отображаться пользователю и как?
Если они являются результатом ошибочного ввода пользователем (например, не числа, плохой электронной почты, нарушения ограничений и т.д.), покажите их в той же форме для пользователя. В противном случае (например, DB down, исключение DAO и т.д.) Либо переместите все до страницы ошибки, либо отобразите ошибку с сообщением, чтобы повторить попытку позже.
6: Как использовать глобальную страницу обработчика исключений?
По крайней мере, в удобной для пользователя форме. Таким образом, в том же макете, с некоторыми вводными "извинениями" и, при необходимости, с некоторыми сведениями об ошибке и адресом электронной почты, чтобы пользователь мог связаться для случая.
7: Как следует использовать в этом контексте ActionErrors?
Показать в той же форме пользователю.
Ответ 2
Если вы не можете восстановиться из исключения, вы должны позволить ему выходить из вашего кода (часто, если он не установлен, или обертывает его в неконтролируемом исключении). Если они остаются проверенными, вы должны обслуживать их на каждом уровне вашего кода и, следовательно, на каждом уровне абстракции. SQLExceptions
обычно попадает в эту категорию (вам придется обернуть их, так как они отмечены).
Для этих исключений я обычно регистрируюсь на самом высоком уровне, но представляю страницу пользователям, просто детализируя, что что-то пошло не так. Обычно мои пользователи не интересуются трассировкой стека. Но я обычно предлагаю им страницу, чтобы дать им описание того, что они делали в то время, и зарегистрированное исключение связано с этим представлением через уникальный идентификатор (записанный в форме и в файле журнала с исключением). Это позволяет мне привязывать действия пользователей к полученному исключению.
Вышеизложенное предполагает, что вы не можете восстановиться после SQLExceptions
, и если база данных не работает, то вы не можете сделать что-то значимое. Конечно, есть исключения. Вы можете обнаружить, что разговариваете с несколькими системами, а один из них не означает, что вы не можете продолжать каким-либо образом (например, домашняя страница Amazon, как сообщается, использует 100 сервисов и должна работать независимо от того, вниз).
Я ожидаю, что объявленные исключения будут на том же уровне абстракции, что и интерфейс/методы, определяющие их. например a TradeStore
будет объявлен, чтобы бросить TradeException
, а не SQLException
(так как методы хранения торговли - это реализация TradeStore
- вы можете сохранить в реляционном db, JavaSpace и т.д.).
Ответ 3
Как предупреждение, при отображении сообщений об ошибках нижнего уровня пользователям, убедитесь, что они дезинфицированы из системной информации. Это область, в которой происходят многие нарушения безопасности. Запишите их с полной информацией, но отобразите более общее сообщение об ошибке пользователю.