For some reason, I do whatever tutorial on Struts exception handling http://struts.apache.org/2.1.8.1/docs/exception-handling.html and yet the Struts giving me that obscure error message at package nodes.
It is said
The content of element type “package” must match “(result-types?,interceptors?,default-interceptor-ref?,default-
action-ref?,default-class-ref?,global-results?,global-exception-mappings?,action*)”.
I have no idea what is it until I see the tutorial mentions that I need to add two important nodes which I gladly copy pasted.
<global-exception-mappings>
<exception-mapping exception="org.apache.struts.register.exceptions.SecurityBreachException" result="securityerror" />
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
<global-results>
<result name="securityerror">/securityerror.jsp</result>
<result name="error">/error.jsp</result>
</global-results>
It took me 15 minutes to figure out that the tutorial gives me the wrong sequence of nodes. I need to do global-result before global-exception-mappings. Making the correct sequence to be:
<global-results>
<result name="securityerror">/securityerror.jsp</result>
<result name="error">/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="org.apache.struts.register.exceptions.SecurityBreachException" result="securityerror" />
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
and based on the above mentioned error notification and seeing the tutorial sample file, I could piece up the final struts.xml. In case you are lazy bum who do not want to download that extra 3.5 mb zip files and (assuming you follow the tutorial faithfully), the final struts.xml at the end of the day should be
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.custom.i18n.resources" value="global" />
<package name="basicstruts2" extends="struts-default">
<!--
setup the default-stack exception mapping interceptor so that any
exceptions not caught by this application will be logged and then
handled by the global exception mapping
-->
<!--
You can configure the Struts 2 framework to log any uncaught
exceptions. To enable logging of the exceptions being handled by the
Struts 2 framework you must specify some parameter values in
struts.xml. If you examine the ExceptionMappingInterceptor class API
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="appDefault">
<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="appDefault" />
<!--
To enable global exception handling you need to add two nodes to
struts.xml: global-exception-mapping and global-results. For example
examine struts.xml from the Exception Handling code download
(http://code.google.com/p/struts2-examples/downloads/list).
-->
<global-results>
<result name="error">/error.jsp</result>
<result name="securityerror">/securityerror.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping
exception="org.apache.struts.register.exceptions.SecurityBreachException"
result="securityerror" />
<exception-mapping exception="java.lang.Exception"
result="error" />
</global-exception-mappings>
<action name="causesecurityexception" class="org.apache.struts.register.action.Register"
method="throwSecurityException">
<result>/register.jsp</result>
</action>
<action name="causeexception" class="org.apache.struts.register.action.Register"
method="throwException">
<result>/register.jsp</result>
</action>
<action name="causenullpointerexception" class="org.apache.struts.register.action.Register"
method="throwNullPointerException">
<result>/register.jsp</result>
</action>
<!--
If you need to handle an exception in a specific way for a certain
action you can use the exception-mapping node within the action node.
-->
<action name="actionspecificexception" class="org.apache.struts.register.action.Register"
method="throwSecurityException">
<exception-mapping
exception="org.apache.struts.register.exceptions.SecurityBreachException"
result="login" />
<result>/register.jsp</result>
<result name="login">/login.jsp</result>
</action>
<action name="index">
<result>/index.jsp</result>
</action>
<action name="hello"
class="org.apache.struts.helloworld.action.HelloWorldAction" method="execute">
<result name="success">/HelloWorld.jsp</result>
</action>
<action name="register" class="org.apache.struts.register.action.Register"
method="execute">
<result name="success">/thankyou.jsp</result>
<result name="input">/register.jsp</result>
</action>
<action name="registerInput" class="org.apache.struts.register.action.Register"
method="input">
<result name="input">/register.jsp</result>
</action>
</package>
</struts>