原文地址:[url]http://www.brucephillips.name/blog/index.cfm/2009/12/8/Struts-2-Global-Exception-Handling-With-Logging[/url]
Struts 2 Global Exception Handling With Logging
Posted At : December 8, 2009 5:15 PM | Posted By : Bruce Phillips
Related Categories: Java
Introduction
One of the perks of my current job is I work with a pretty smart group of Java developers. Jeff Day, one of the programmers here at KU, showed me how to enable logging when using Struts 2's global exception handling mechanism.
Global Exception Handling
I've been using global exception handling (see ref. 3) to handle runtime exceptions my application may throw but that I don't catch explicitly. For example in struts.xml:
<global-results>
<result name="error">/error.jsp</result>
<result name="securityerror">/securityerror.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="edu.ku.it.si.struts2_jsp_example.exceptions.SecurityBreachException" result="securityerror" />
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
Any exception that inherits from java.lang.Exception that is thrown but not caught by my application will be handled by the Struts 2 framework (specifically the ExceptionMappingInterceptor [ref. 2]) and the user's browser will be directed to error.jsp.
Enable Logging
What my clever co-worker Jeff showed me was that you can enable logging of the exceptions being handled by the Struts 2 framework by specifying some parameter values in struts.xml. If you examine the ExceptionMappingInterceptor class API (ref. 2) there are three parameter values you can set to enable logging (logEnabled), the log level to use (logLevel), and the log category (logCategory) to specify in the log message.
To set these parameter values for all actions that use a specific stack of interceptors in a package include the following in struts.xml just after the opening package node.
<interceptors>
<interceptor-stack name="appDefaultStack">
<interceptor-ref name="defaultStack">
<param name="exception.logEnabled">true</param>
<param name="exception.logLevel">ERROR</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="appDefaultStack" />
In the above xml I'm configuring a new stack of Struts 2 interceptors named appDefaultStack. This stack of interceptors is based upon the defaultStack of interceptors. The ExceptionMappingInterceptor is one of the Struts 2 interceptors that is part of the default stack (ref. 3). In the definition of the struts defaultStack, the ExceptionMappingInterceptor is given the name of exception. By specifying a param node with the name of exception.logEnabled and a value of true, I'm setting the logEnabled parameter of the ExceptionMappingInterceptor class to true.
Now when my application throws an exception that I'm not catching, the Struts 2 framework will handle it and also write an entry to my log that includes the stack trace. In my example above, I've set the level to log these exceptions to be ERROR.
Example Application
I created a simple Struts 2 web application that demonstrates using global exception handling and logging (ref. 1). The example application was created using Eclipse 3.5 with the Maven 2 plugin. You should be able to import the archive download directly into Eclipse.
If you are not using Eclipse, unzip the download and if your Java IDE supports importing Maven projects import the unzipped project.
You can run the application using the Maven command mvn jetty:run in a command (terminal) window after navigating to the project's root folder (the location of Maven's pom.xml file). When you see "[INFO] Started Jetty Server" in the command window open a web browser and load this URL: http://localhost:8080/struts2jspexample/index.jsp.
When the web page opens there will be some links you can click on to call Struts 2 actions that generate exceptions. When you click on these actions note the log message written to the Jetty console (the log4j.xml for this project just logs to the console).
To stop the Jetty server type CTRL-C in the command window.
Summary
Logging the exceptions thrown and being handled by Struts 2 global exception handling mechanism is useful during development and production. During development you could also display the exception details using the s:property value="exception" and s:property value="exceptionStack" tags in the JSP that is mapped to the exception. But of course in production you'd would not want to expose those details to the user. By setting the logging parameters Struts 2 will write the exception information to your log files.
References
Example Struts 2 Project, Global Exception Handling With Logging
Class ExceptionMappingInterceptor, Struts 2.1.8.1 API
Exception Configuration, Apache Struts 2 Documentation
Struts 2 in Action, Donald Brown, Chad Michael Davis, and Scott Stanlick, Manning (2008), pages 88-89
Apache Struts 2 Web Application Development, Dave Newton, Packt (2009), page 173, pages 193-195
Comments (1) | Print | Send | del.icio.us | Digg It! | Linking Blogs | 3717 Views
Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
[Add Comment] [Subscribe to Comments]
To enable your Struts 2 portlet application to log all uncaught exceptions and redirect the user to an error portlet view add the following after the package opening node:
[color=red]<interceptors>
<interceptor-stack name="appDefault">
<interceptor-ref name="portletDefaultStack">
<param name="exception.logEnabled">true</param>
<param name="exception.logLevel">ERROR</param>
</interceptor-ref>
</interceptor-stack>[/color]
</interceptors>
<default-interceptor-ref name="appDefault" />
<global-results>
<result name="error">/portlet/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
In a standard Struts 2 web application the interceptor-ref line is just <interceptor-ref name="defaultStack"> but because a Struts 2 portlet application uses a package statement that extends struts-portlet-default, the interceptor-ref must have a name value of portletDefaultStack.
# Posted By Bruce | 1/4/10 11:19 AM
Struts 2 Global Exception Handling With Logging
Posted At : December 8, 2009 5:15 PM | Posted By : Bruce Phillips
Related Categories: Java
Introduction
One of the perks of my current job is I work with a pretty smart group of Java developers. Jeff Day, one of the programmers here at KU, showed me how to enable logging when using Struts 2's global exception handling mechanism.
Global Exception Handling
I've been using global exception handling (see ref. 3) to handle runtime exceptions my application may throw but that I don't catch explicitly. For example in struts.xml:
<global-results>
<result name="error">/error.jsp</result>
<result name="securityerror">/securityerror.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="edu.ku.it.si.struts2_jsp_example.exceptions.SecurityBreachException" result="securityerror" />
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
Any exception that inherits from java.lang.Exception that is thrown but not caught by my application will be handled by the Struts 2 framework (specifically the ExceptionMappingInterceptor [ref. 2]) and the user's browser will be directed to error.jsp.
Enable Logging
What my clever co-worker Jeff showed me was that you can enable logging of the exceptions being handled by the Struts 2 framework by specifying some parameter values in struts.xml. If you examine the ExceptionMappingInterceptor class API (ref. 2) there are three parameter values you can set to enable logging (logEnabled), the log level to use (logLevel), and the log category (logCategory) to specify in the log message.
To set these parameter values for all actions that use a specific stack of interceptors in a package include the following in struts.xml just after the opening package node.
<interceptors>
<interceptor-stack name="appDefaultStack">
<interceptor-ref name="defaultStack">
<param name="exception.logEnabled">true</param>
<param name="exception.logLevel">ERROR</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="appDefaultStack" />
In the above xml I'm configuring a new stack of Struts 2 interceptors named appDefaultStack. This stack of interceptors is based upon the defaultStack of interceptors. The ExceptionMappingInterceptor is one of the Struts 2 interceptors that is part of the default stack (ref. 3). In the definition of the struts defaultStack, the ExceptionMappingInterceptor is given the name of exception. By specifying a param node with the name of exception.logEnabled and a value of true, I'm setting the logEnabled parameter of the ExceptionMappingInterceptor class to true.
Now when my application throws an exception that I'm not catching, the Struts 2 framework will handle it and also write an entry to my log that includes the stack trace. In my example above, I've set the level to log these exceptions to be ERROR.
Example Application
I created a simple Struts 2 web application that demonstrates using global exception handling and logging (ref. 1). The example application was created using Eclipse 3.5 with the Maven 2 plugin. You should be able to import the archive download directly into Eclipse.
If you are not using Eclipse, unzip the download and if your Java IDE supports importing Maven projects import the unzipped project.
You can run the application using the Maven command mvn jetty:run in a command (terminal) window after navigating to the project's root folder (the location of Maven's pom.xml file). When you see "[INFO] Started Jetty Server" in the command window open a web browser and load this URL: http://localhost:8080/struts2jspexample/index.jsp.
When the web page opens there will be some links you can click on to call Struts 2 actions that generate exceptions. When you click on these actions note the log message written to the Jetty console (the log4j.xml for this project just logs to the console).
To stop the Jetty server type CTRL-C in the command window.
Summary
Logging the exceptions thrown and being handled by Struts 2 global exception handling mechanism is useful during development and production. During development you could also display the exception details using the s:property value="exception" and s:property value="exceptionStack" tags in the JSP that is mapped to the exception. But of course in production you'd would not want to expose those details to the user. By setting the logging parameters Struts 2 will write the exception information to your log files.
References
Example Struts 2 Project, Global Exception Handling With Logging
Class ExceptionMappingInterceptor, Struts 2.1.8.1 API
Exception Configuration, Apache Struts 2 Documentation
Struts 2 in Action, Donald Brown, Chad Michael Davis, and Scott Stanlick, Manning (2008), pages 88-89
Apache Struts 2 Web Application Development, Dave Newton, Packt (2009), page 173, pages 193-195
Comments (1) | Print | Send | del.icio.us | Digg It! | Linking Blogs | 3717 Views
Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
[Add Comment] [Subscribe to Comments]
To enable your Struts 2 portlet application to log all uncaught exceptions and redirect the user to an error portlet view add the following after the package opening node:
[color=red]<interceptors>
<interceptor-stack name="appDefault">
<interceptor-ref name="portletDefaultStack">
<param name="exception.logEnabled">true</param>
<param name="exception.logLevel">ERROR</param>
</interceptor-ref>
</interceptor-stack>[/color]
</interceptors>
<default-interceptor-ref name="appDefault" />
<global-results>
<result name="error">/portlet/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
In a standard Struts 2 web application the interceptor-ref line is just <interceptor-ref name="defaultStack"> but because a Struts 2 portlet application uses a package statement that extends struts-portlet-default, the interceptor-ref must have a name value of portletDefaultStack.
# Posted By Bruce | 1/4/10 11:19 AM