Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struts2 .action extension causing CSS, JavaScript and Struts Dojo to break

We have been running on Struts 2.1.8 for some time and all Struts actions have been working as expected, i.e. href's to the Struts actions are rendered with the action name with no extension.

Here is the JSP code that set's up the links:

<ul id="top_menu">
  <li id="itemHome" class="active"><s:a action="viewHome">Home</s:a></li>
  <li><s:a action="viewSearch">Search</s:a></li>
  <li><s:a action="viewBookMarks">My Bookmarks</s:a></li>
  <li><s:a action="viewSupport">Support</s:a></li>
</ul>

The links rendered correctly to http://localhost/viewHome, http://localhost/viewSearch, etc. under 2.1.8

We just upgraded to Struts 2.2.1 (an have checked all versions from this up to v2.3.4.1) and are now seeing Struts actions links are rendering as http://localhost/viewHome.action, http://localhost/viewSearch.action, etc.

My research has shown that the general suggested solution is to use

<constant name="struts.action.extension" value=""/>

in struts.xml to remove the .action suffix. Whilst this makes the URLs render correctly it is causing an unexpected side effect. Struts now thinks every URL is an action including requests for .css, .png, etc.

My filter-mapping in web.xml has not changed. And although it sends /* to Struts we didn't see this behavior under 2.1.8

<filter>
   <filter-name>struts2</filter-name>
   <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>   
</filter>

<filter-mapping>
   <filter-name>struts2</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

To counteract this I've had to use the excludePattern to stop Struts trying to treat these requests as actions.

<constant name="struts.action.excludePattern" value="/index.html,/images/.*,/js/.*,/css/.*"/>

Whilst this works, the last hurdle is that my logs are full of errors from Struts tags requests that are being handled as Struts actions. When I add these URI's to the exclude pattern then Struts Dojo tags don't seem to be working in some pages.

The parts of struts.xml affected are:

<constant name="struts.devMode" value="true" />
<!-- Set URL's to have no .action extension -->
<constant name="struts.action.extension" value=""/>
<constant name="struts.action.excludePattern" value="/index.html,/images/.*,/js/.*,/css/.*"/>

And an example of the Struts errors in the log is:

2012-09-26 17:12:57,984 [http-bio-8080-exec-9] ERROR org.apache.struts2.dispatcher.Dispatcher- Could not find action or result
/struts/dojo/struts_dojo.js
There is no Action mapped for namespace [/] and action name [struts_dojo.js] associated with context path []. - [unknown location]
    at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:185)
    at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
    at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:501)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)

I'm not sure if the struts Dojo requests are real URI's or virtual or something else.

It feels at this point that I've jumped through quite a few hoops to fix what is essentially a simple problem of removing the .action extension from URL's given that going back to the 2.1.8 JAR solves everything but I'm determined to find a way forward if possible.

Any help is very much appreciated.

like image 605
Greg Kennedy Avatar asked Sep 26 '12 17:09

Greg Kennedy


People also ask

What is the use of web xml file in Struts?

In the web. xml file, Struts defines its FilterDispatcher, the Servlet Filter class that initializes the Struts framework and handles all requests. This filter can contain initialization parameters that affect what, if any, additional configuration files are loaded and how the framework should behave.

What is ActionSupport in struts2?

public class ActionSupport extends Object implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable. Provides a default implementation for the most common actions. See the documentation for all the interfaces this class implements for more detailed information.

What is action tag struts?

The action tag allows the programmers to execute an action from the view page. They can achieve this by specifying the action name. They can set the "executeResult" parameter to "true" to render the result directly in the view.


1 Answers

Try to use struts action exstension with comma like this
<constant name="struts.action.extension" value=","/>.
From the struts2 properties file:

Used by the DefaultActionMapper You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do The blank extension allows you to match directory listings as well as pure action names without interfering with static resources, which can be specified as an empty string prior to a comma e.g. struts.action.extension=, or struts.action.extension=x,y,z,, struts.action.extension=action,,

like image 86
Aleksandr M Avatar answered Oct 18 '22 20:10

Aleksandr M