Вместо того, чтобы писать больше комментариев (лишний избыток), я поместил некоторые из своих мыслей здесь + один вид общего решения, с которым я столкнулся.
http://docs.oracle.com/javaee/6/tutorial/doc/bnbpj.html
Это ставит этот вопрос в простом контексте. Когда люди не привыкли к исключениям (например, скрипты/функциональные программисты), они говорят о том, что используют только RuntimeExceptions ..., которые заставляют вас загрязнять внешний интерфейс с неуправляемыми ошибками, возникающими в пользовательском интерфейсе. (Я не считаю, что очень удобно, если вы считаете, программный код в долгосрочной перспективе ... ремонтопригодности)
http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html
Если клиент может занять некоторое альтернативное действие, чтобы оправиться от исключения, сделать это проверенное исключение. Если клиент не может сделать ничего полезного, сделайте исключение непроверенным. К полезным, я имею в виду принятие мер для восстановления из исключения, а не только для регистрации исключения.
(Есть сообщения о лесозаготовительных модели с исключениями, но я не буду там в этом, как она замолкает)
трудно обнаружить непроверенные исключения, и они легко получить передать свой «близко к источнику «ловить. (Если они не отмечены, они будут невидимы для кода клиента и проскользнут).
Мне поставили под сомнение эту проблему с некоторым устаревшим кодом, бросающим много неконтролируемых исключений, которые теперь приводят к крушению пользовательского интерфейса. (из-за ненадежных услуг)
Возможно, «у каждого» есть свое мнение, как правильно поступать, но я пытаюсь создать общий шаблон для обнаружения ошибок (исключенных исключений), близких к пользовательскому интерфейсу, и представления их с хорошей ошибкой popups (JSF кстати) вместо того, чтобы направлять пользователя на страницу «error.xhtml» (введено в web.xml).
// Для вышеуказанного сценария я придумал это решение.
Это даже, кажется, работает очень хорошо.
- Создайте аннотацию привязки перехватчика и перехватчика.
- Аннотировать классы или методы, по которым вы хотите, чтобы их пузырящиеся EJBExceptions были дезинфицированы.
- Не перехватывайте все или не получаете ненужную обработку/накладные расходы. Просто используйте его там, где он вам действительно нужен, на уровне BackingBean/ManagedBean.
Перехватчик связывания аннотаций
@Inherited
@InterceptorBinding
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface InterceptEJBExceptions {}
Перехватчик
@Interceptor
@InterceptEJBExceptions
public class EjbExceptionInterceptor {
@AroundInvoke
public Object interceptBubblingExceptions(final InvocationContext context) throws Exception {
try {
return context.proceed();
} catch (MySpecificEJBException msejbe) {
Object[] args = { msejbe.getErrorCode(), msejbe.getMethodSignature(), msejbe.getParameters()};
// This would create a FacesMessage in JSF
addErrorMessageToFacesContext(null, summary_template, details_template, args);
} catch (EJBException ejbe) {
super.addErrorMessageToFacesContext(null, "Unspecified EJBException", ejbe.getMessage());
}
// "Pure" RuntimeExceptions will fall through and will be shown on 'error-page' specified in web.xml
return null;
}
}
beans.xml
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>xxx.xxx.xxx.exception.interceptor.EjbExceptionInterceptor</class>
</interceptors>
</beans>
Использование в Java-Классе s
@RequestScoped // Class must be in EE context
// @InterceptEJBExceptions // Have the annotation at class level to intercept all method calls in this class
public class MyBB {
@InterceptEJBExceptions // Only intercept when this method gets called
public String myEjbExceptionThrowingActionListener(Object obj) {
// Some code that may throw an EJBException
}
}
MySpecificEJBException бы класс Exception расширения EJBException. Постройте класс так, как вам нравится переносить полезную информацию для последующего ведения журнала и для отображения чистых сообщений об ошибках на экране вместо того, чтобы вызывать исключение на экране с или без error-страница, определенная в web.xml (что также должно имеют в качестве резерва).
Не забудьте указать оригинальное исключение в классе!
Создайте больше своих собственных Исключений, расширяющих EJBException по мере необходимости и бросайте их по своему усмотрению (в качестве RuntimeExceptions они не отмечены). Затем просто добавьте блок catch в перехватчик и сделайте сообщение о регистрации и/или ошибке, отображаемое для этого случая.
В общем:
Используйте проверенные исключения, где вы можете реагировать на ошибки.
В Java 7 вы можете использовать следующий синтаксис для группировки Исключения, которые можно обрабатывать аналогичным образом.
попробовать {...} задвижка (SomeException | OtherException е) {...}
Если у вас есть много проверяемых исключений, вы можете/должны, возможно, сгруппировать их по категориям (расширить некоторые более общее исключение). Затем вы можете поймать на основе этого исключения группировки (в дополнение к/вместо группировки catch-clauses).
- Включите эти исключения в EJB/RuntimeExceptions, которые загрязняют вас кодом (если вы действительно ничего не можете сделать близко). Затем они должны быть захвачены и обработаны общим кодом EjbExceptionInterceptor. Перехватчик поймает исключение => покажет чистое сообщение об ошибке/всплывающее окно, но пользователь останется на одной странице без потери данных, над которыми он/она работал.
- Избегать бросать равнину RuntimeException. Они сигнализируют ошибку в коде (мое мнение) и вышеперечисленный перехватчик позволят им провалиться на странице ошибок . Это также отключит пользователя от страницы, на которой он сейчас находится.
- Эти ошибки должны быть всегда исправлены с высоким приоритетом (например, NullPointerException сделает это).
- Также: Не бросайте Исключения практически обо всем, это будет плохое программирование. Если ваш код может что-то сделать с ошибкой перед рукой (например, использовать перегруженные методы или значения по умолчанию, чтобы предотвратить использование нулевых параметров), тогда сделайте это, не пропустите проблему клиенту (метод вызова). Это просто ленивое программирование + использование RuntimeExceptions, чтобы скрыть эти ошибки, просто безответственно! Пробные испытания!
Я не смог найти какое-либо фактическое решения для обработки (как образец) ошибки, но через много дискуссий, что правильно и что неправильно. У нас есть 2 типа Throwables, так почему бы им не использовать их конструктивно?
Вместо продолжения этой дискуссии я надеюсь, что это будет реальное решение и сделает трюк.
Буду признателен всем конструктивным комментариям и предложениям по улучшению.
-1, для многих проверенных исключений была плохая идея, прочитал Джошуа Блоха, Брюса Эккела и многих других ... И посмотрите на любые современные Java-рамки. Spring, Hibernate, JPA, CXF ... все они используют исключенные исключения, и это прекрасно, чтобы поймать DataAccessException для создания определенного рабочего процесса. –
Обратите внимание, что создатели C# вдохнули вдохновение из Java и решили не помещать проверенный механизм исключения в C#, потому что это считается некорректной функцией. Даже Scala не выполняла проверенные исключения. –
Вместо того, чтобы подавлять нисходящие голоса от гнева, не стесняйтесь объяснять, почему вы не согласны с тем, что я ответил. –