Hallo java folks!
Ich sitze hier gerade an einem mittleren Webprojekt als Übung für die Uni. Es handelt sich dabei um ein Webportal. Ich bin gerade dabei das Exception-Handling einzufügen.
Generelles
Unbehandelte Exceptions, werden generell durch folgenden Eintrag in der web.xml auf ein Servlet gemapt:
Das Servlet, dass die Exceptions behandelt, extrahiert ein paar Informationen über die Exception aus dem request und leitet diese dann auf eine Jsp weiter.
Soweit so gut, funktioniert alles. Jetzt muss ich allerdings noch etwas weiter ausholen um meine Frage zu erläutern.
Http-Anfragen werden in diesem Projekt entweder auf ein Frontend-Servlet oder ein Backend-Servlet gemapt. Diese leiten die Anfragen dann an jeweils eine Factory, die an Hand des Querystrings die passende Action-Klasse erzeugt. Das Servlet führt dann auf dieser Klasse eine doAction-Methode aus, welche dann die eigentlich Ablaufsteuerung enthält. Die Eltern-Action kümmert sich um generelle Sachen wie beispielsweise die Autentifizierung, so dass sich in den Action-Klassen lediglich die folgenden zwei Methoden unterscheiden.
[Java] @Override
protected abstract String executeCommand(HttpServletRequest request,
HttpServletResponse response, String queryString, String tld)
throws DaoException;
@Override
protected abstract void setContent(HttpServletRequest request,
String queryString, String tld) throws DaoException;[/Java]
Diese beiden werfen nun auftretende DaoExceptions, die während dem Zugriff auf die Datenbank auftreten können, weiter an die doAction()-Methode. Dort wird die Exception dann letztendlich gefangen und bisher wird die Request URL gesäubert, so dass einfach nur die entsprechende JSP-Seite ohne ein etwaiges Kommando (im Querystring aufgerufen wird).
[Java] @Override
public String doAction(HttpServletRequest request,
HttpServletResponse response) {
try {
if (request.getCharacterEncoding() == null) {
request.setCharacterEncoding("UTF-8");
}
} catch (UnsupportedEncodingException e) {
logger.error(e.getMessage());
}
logger.debug("Encoding: " + request.getCharacterEncoding() + ".");
String userName = (String) request.getSession()
.getAttribute("userName");
logger.debug("Executing " + this.getClass() + ".");
if (!checkCredentials(userName)) {
return forwardToStatusPage(request, response, tld, new StatusBean(
"hdg_authError", "txt_authError"));
}
this.userName = userName;
try {
String forward = executeCommand(request, response, queryString, tld);
if (forward != null) {
return forward;
}
preparePage(request, response);
} catch (DaoException e) {
logger.error(e.getMessage());
queryString = QueryStringFormatter
.getQueryStringForAction(QueryStringFormatter
.getAction(queryString));
}
return FrontendActionFactory.JSP_INDEX;
}
[/Java]
Jetzt bin ich am überlegen wie ich das mit den Exceptions mache. Sollte ich nicht vielleicht die auftretende DaoException bis hoch zum ExceptionHandler-Servlet werfen? Also quasi "public String doAction(HttpServletRequest request,
HttpServletResponse response) throws DaoException"...
Die executeCommand() überprüft den QueryString auf einen command-Teil. Dies ist ein String der in der executeCommand extrahiert wird und an Hand dessen dann bestimmte Aktionen ausgeführt werden. Falls kein command-Teil übergeben wurde, wird null zurückgegeben und die preparePage()-Methode wird ausgeführt. Bisher ist es so, dass wenn ein gültiger Command-Teil übergeben wird, aber fehlerhafte Parameter zu diesem Kommando (beispielsweise eine Id), gibt diese auch einfach null zurück. Siehe nachfolgender Code:
[Java] @Override
protected String executeCommand(HttpServletRequest request,
HttpServletResponse response, String queryString, String tld)
throws DaoException {
logger.debug("Executing commands in " + this.getClass());
String command = QueryStringFormatter.getCommand(queryString);
if (command == null || command.isEmpty()) {
logger.debug("No command was given. [" + queryString + "]");
return null;
} else if (command.equals("showItem") || command.equals("hideItem")) {
return hideShow(request, response, queryString, command, tld);
} else if (command.equals("sort")) {
logger.debug("Sorting the content items.");
return sort(request, response, queryString, tld);
} else if (command.equals("changeOrderType")) {
logger.debug("Changing the order type.");
return changeOrderType(request, response, queryString, tld);
} else {
logger.debug("Invalid command was given. [" + queryString + "]");
return null;
}
}[/Java]
Ich bin nun am überlegen ob ich im letzten else-Teil statt dem "return null" eine MalformedSyntaxException (eigene Exception) werfe, die dann bis rauf zum Servlet geworfen wird.
Lange Rede - kurzer Sinn:
Eigene Exceptions werfen - gut oder böse? (Hier kommt es mir vor allem auf guten Stil an, Konventionen und so)
Exceptions so schnell wie möglich abfangen oder auch mal weiterwerfen?
Den Benutzer mit Fehlerseiten beunruhigen oder durch interne Säuberung des QueryString nicht darüber informieren, dass jetzt etwas nicht funktioniert hat, wie er eigentlich wollte.
"Exception-Throws" so speziell wie möglich definieren oder nicht? (Ich denke hierbei an bsp. das FrontendServlet: doPost(...) throws ServletException, IoException, DaoException, AuthorizationException, MalformedSyntaxException VS. doPost(...) throws Exception)
Wie macht ihr das in eure Projekten? Habt ihr vielleicht auch Links zu Seiten die sich etwas mit Exceptionhandling auf Servlets/Jsps befassen?
Bin für jede Anregung dankbar!
Grüße
Ich sitze hier gerade an einem mittleren Webprojekt als Übung für die Uni. Es handelt sich dabei um ein Webportal. Ich bin gerade dabei das Exception-Handling einzufügen.
Generelles
Unbehandelte Exceptions, werden generell durch folgenden Eintrag in der web.xml auf ein Servlet gemapt:
Code:
<servlet>
<description>Handles all exceptions.</description>
<servlet-name>ExceptionHandler</servlet-name>
<servlet-class>de.controller.utilities.ExceptionHandler</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ExceptionHandler</servlet-name>
<url-pattern>/error</url-pattern>
</servlet-mapping>
<servlet>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error/error404.jsp</location>
</error-page>
[... weitere error codes ...]
Das Servlet, dass die Exceptions behandelt, extrahiert ein paar Informationen über die Exception aus dem request und leitet diese dann auf eine Jsp weiter.
Soweit so gut, funktioniert alles. Jetzt muss ich allerdings noch etwas weiter ausholen um meine Frage zu erläutern.
Http-Anfragen werden in diesem Projekt entweder auf ein Frontend-Servlet oder ein Backend-Servlet gemapt. Diese leiten die Anfragen dann an jeweils eine Factory, die an Hand des Querystrings die passende Action-Klasse erzeugt. Das Servlet führt dann auf dieser Klasse eine doAction-Methode aus, welche dann die eigentlich Ablaufsteuerung enthält. Die Eltern-Action kümmert sich um generelle Sachen wie beispielsweise die Autentifizierung, so dass sich in den Action-Klassen lediglich die folgenden zwei Methoden unterscheiden.
[Java] @Override
protected abstract String executeCommand(HttpServletRequest request,
HttpServletResponse response, String queryString, String tld)
throws DaoException;
@Override
protected abstract void setContent(HttpServletRequest request,
String queryString, String tld) throws DaoException;[/Java]
Diese beiden werfen nun auftretende DaoExceptions, die während dem Zugriff auf die Datenbank auftreten können, weiter an die doAction()-Methode. Dort wird die Exception dann letztendlich gefangen und bisher wird die Request URL gesäubert, so dass einfach nur die entsprechende JSP-Seite ohne ein etwaiges Kommando (im Querystring aufgerufen wird).
[Java] @Override
public String doAction(HttpServletRequest request,
HttpServletResponse response) {
try {
if (request.getCharacterEncoding() == null) {
request.setCharacterEncoding("UTF-8");
}
} catch (UnsupportedEncodingException e) {
logger.error(e.getMessage());
}
logger.debug("Encoding: " + request.getCharacterEncoding() + ".");
String userName = (String) request.getSession()
.getAttribute("userName");
logger.debug("Executing " + this.getClass() + ".");
if (!checkCredentials(userName)) {
return forwardToStatusPage(request, response, tld, new StatusBean(
"hdg_authError", "txt_authError"));
}
this.userName = userName;
try {
String forward = executeCommand(request, response, queryString, tld);
if (forward != null) {
return forward;
}
preparePage(request, response);
} catch (DaoException e) {
logger.error(e.getMessage());
queryString = QueryStringFormatter
.getQueryStringForAction(QueryStringFormatter
.getAction(queryString));
}
return FrontendActionFactory.JSP_INDEX;
}
[/Java]
Jetzt bin ich am überlegen wie ich das mit den Exceptions mache. Sollte ich nicht vielleicht die auftretende DaoException bis hoch zum ExceptionHandler-Servlet werfen? Also quasi "public String doAction(HttpServletRequest request,
HttpServletResponse response) throws DaoException"...
Die executeCommand() überprüft den QueryString auf einen command-Teil. Dies ist ein String der in der executeCommand extrahiert wird und an Hand dessen dann bestimmte Aktionen ausgeführt werden. Falls kein command-Teil übergeben wurde, wird null zurückgegeben und die preparePage()-Methode wird ausgeführt. Bisher ist es so, dass wenn ein gültiger Command-Teil übergeben wird, aber fehlerhafte Parameter zu diesem Kommando (beispielsweise eine Id), gibt diese auch einfach null zurück. Siehe nachfolgender Code:
[Java] @Override
protected String executeCommand(HttpServletRequest request,
HttpServletResponse response, String queryString, String tld)
throws DaoException {
logger.debug("Executing commands in " + this.getClass());
String command = QueryStringFormatter.getCommand(queryString);
if (command == null || command.isEmpty()) {
logger.debug("No command was given. [" + queryString + "]");
return null;
} else if (command.equals("showItem") || command.equals("hideItem")) {
return hideShow(request, response, queryString, command, tld);
} else if (command.equals("sort")) {
logger.debug("Sorting the content items.");
return sort(request, response, queryString, tld);
} else if (command.equals("changeOrderType")) {
logger.debug("Changing the order type.");
return changeOrderType(request, response, queryString, tld);
} else {
logger.debug("Invalid command was given. [" + queryString + "]");
return null;
}
}[/Java]
Ich bin nun am überlegen ob ich im letzten else-Teil statt dem "return null" eine MalformedSyntaxException (eigene Exception) werfe, die dann bis rauf zum Servlet geworfen wird.
Lange Rede - kurzer Sinn:
Eigene Exceptions werfen - gut oder böse? (Hier kommt es mir vor allem auf guten Stil an, Konventionen und so)
Exceptions so schnell wie möglich abfangen oder auch mal weiterwerfen?
Den Benutzer mit Fehlerseiten beunruhigen oder durch interne Säuberung des QueryString nicht darüber informieren, dass jetzt etwas nicht funktioniert hat, wie er eigentlich wollte.
"Exception-Throws" so speziell wie möglich definieren oder nicht? (Ich denke hierbei an bsp. das FrontendServlet: doPost(...) throws ServletException, IoException, DaoException, AuthorizationException, MalformedSyntaxException VS. doPost(...) throws Exception)
Wie macht ihr das in eure Projekten? Habt ihr vielleicht auch Links zu Seiten die sich etwas mit Exceptionhandling auf Servlets/Jsps befassen?
Bin für jede Anregung dankbar!
Grüße
Zuletzt bearbeitet: