I'm using the struts2 framework for a webapp. While trying to create a custom 404 error page I discovered Struts2 is doing more work for me then intended.
I only use a struts.xml and a web.xml file. In the web-xml file I added the following code:
<error-page>
<error-code>404</error-code>
<location>/error/Error404.jsp</location>
</error-page>
Now, when I start my webapp it goes to the homepage as usual. When I try urls of this type (all urls that don't exist):
http://localhost:8080/MyWebApp/fhgfhfhfhgfhgfhfhfh
http://localhost:8080/MyWebApp/fhgfhfhfhgfhgfhfhfh.action
Struts will process the request, run the interceptors, and automatically redirect to the default page. I would have expected my 404 error page to be shown on these pages. I even removed this line in struts.xml but it still redirects!
<default-action-ref name="index" />
When I use the following url:
http://localhost:8080/MyWebApp/fhgfhfhfhgfhgfhfhfh.jsp
Struts just shows a blank screen and no request is being procesed (no interceptors, no redirecting...). I find this weird too because I don't see what's invalid about that request (other than the .jsp file that doesn't exist)
So I guess I need to modify my struts.xml so I can override some default redirecting behaviour (I don't want the 404 error to be covered up by going to the homepage), and my web.xml to also handle any arbitrery obscure requests (so any url that is being typed in by the user will at actually be handled instead of just showing blank screens. What am I missing in my configuration?
PS: i'm not talking about java exceptions/errors, but only the http errors. The hava exceptions are handled properly like I want them to behave.
I found the reasons why it was not showing.
The problem with blank screen was as follows: the path to my 404 page was not correct. It should be the path starting from the webContent folder, and starting with a slash "/".
The problem with the default action was probably a server reboot or cache problem. I close my browser and my IDE, and restarted everything. Then the default-action-ref was REALLY gone.
I also discovered another interesting quirk: struts2 handles only action mappings, for example:
http://www.mywebsite.com/webapp/whatever
http://www.mywebsite.com/webapp/whatever.action
but it will NOT handle server resources like this (notice the file extensions)
http://www.mywebsite.com/webapp/whatever.zip
http://www.mywebsite.com/webapp/whatever.jsp
http://www.mywebsite.com/webapp/whatever.html
You can remedy this by adding an additional filter mapping in the web.xml file:
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/error/*</url-pattern>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
To solve this you can simply add default namespace and create a action with reference as *. It will get executed by default if no action matched. Add the code below to struts.xml. It should work fine.
<package name="serveAll" namespace="" extends="struts-default">
<action name="*">
<result>/error.jsp</result>
</action>
</package>
Struts 2 can be also configured to handle unknown action or result, even without default-action-ref
tag it provides a configuration to process such requests.
Generally you can use unknown-handler-stack
tag by the struts2 xml configuration and reference handlers. You should check that what com.opensymphony.xwork2.UnknownHandler
is provided. Also see this answer How to define unknown handler bean.
If you are using a convention plugin it supplies by default convention
unknown handler, which could probably handle your action or result.