Struts2 Action Regular Expression/Wild card for URL - java

I am new to Struts2 but so far I have made decent progress using the API. However, I am stuck at something which I need to get out from. I am using Struts2 with Spring integration. I am writing my Action classes with annotation as like many of you I love annotations.
My requirement is that URLs will be in the following nature:
http://<DOMAIN>/program/program1.jspx
http://<DOMAIN>/program/program2.jspx
http://<DOMAIN>/program/program3.jspx
As you can see there is a certain pattern in the URL with program1, program2 and program3 varying and the rest are all static. I have very easily handled similar situation with Spring MVC (I don't have the option of using Spring MVC for the current project) like "/program/{program_name}.jspx" in my other project.
But when I use the same in struts2 I get the error. My Action class is as follows:
#Result(name="program", location="program", type="tiles")
public class ProgramAction extends ActionSupport {
#Action("program/{programName}")
public String getProgramPage() {
// few more lines of code
return "program";
}
}
The error is
2013-02-28 15:46:35.591 WARN [http-bio-8080-exec-3] CommonsLogger.java:60
Could not find action or result
com.opensymphony.xwork2.config.ConfigurationException: There is no Action mapped for namespace / and action name program1.
at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:189) ~[xwork-core-2.2.1.jar:2.2.1]
at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:61) ~[struts2-core-2.2.1.jar:2.2.1]
at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39) ~[struts2-core-2.2.1.jar:2.2.1]
at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58) ~[xwork-core-2.2.1.jar:2.2.1]
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:475) ~[struts2-core-2.2.1.jar:2.2.1]
....
....
My struts.xml file is as follows:
<struts>
<constant name="struts.convention.default.parent.package" value="default"/>
<constant name="struts.action.extension" value="jspx" />
<constant name="struts.mapper.alwaysSelectFullNamespace" value="false" />
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="default" extends="struts-default, json-default, rest-default" namespace="/">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
<result-type name="json" class="org.apache.struts2.json.JSONResult"/>
</result-types>
</package>
</struts>

You have a slash in your action name. struts by default does not like this to correct that add:
<constant name="struts.enable.SlashesInActionNames" value="true"/>

This is because you defined the action annotation on method. Try <s:a namespace="/" action="program/program1" method="programPage" /> in the JSP.

Related

Custom method struts2 rest plugin

Like default mapping logic, I want to create my own custom method for rest service.
Default method to edit new movie: GET: /movies/new => method=editNew
My custom method: GET: /movies/customMethod => method=customMethod
The custom method not allow ID parameter.
Other custom method:
My custom method: POST: /movies/{ID}/customMethod => method=customMethod
My custom method: GET: /movies/{ID}/actors => method=actorOfOneMovie
My configuration:
<constant name="struts.mapper.class" value="org.apache.struts2.dispatcher.mapper.PrefixBasedActionMapper" />
<constant name="struts.mapper.prefixMapping" value="/api:rest, :struts"/>
<constant name="struts.mapper.alwaysSelectFullNamespace" value="false" />
<constant name="struts.enable.SlashesInActionNames" value="false" />
<constant name="struts.convention.action.suffix" value="Action, Controller" />
<constant name="struts.convention.action.mapAllMatches" value="true" />
<constant name="struts.convention.default.parent.package" value="rest-default" />
<constant name="struts.convention.package.locators" value="api" />
<constant name="struts.rest.namespace" value="/api" />
<constant name="struts.rest.defaultExtension" value="json" />
and relative package:
<package name="api" namespace="/api" extends="rest-default">
<result-types>
<result-type name="redirect"
class="org.apache.struts2.dispatcher.ServletRedirectResult">
<param name="statusCode">303</param>
</result-type>
<result-type name="redirectAction"
class="org.apache.struts2.dispatcher.ServletActionRedirectResult">
<param name="statusCode">303</param>
</result-type>
</result-types>
<action name="movies/*" class="api.MoviesController">
<param name="id">{1}</param>
</action>
With this configuration, examples 1, 3 and 4 are working properly.
If I call the example 2, struts2 maps the URL with the default method show.
Questions:
Is there a configuration that permits my case - i.e., creating a customMethod?
Is it possible to restrict http requests to a specific VERB?

How to allow slashes in Struts 2 Action Names?

I'm trying to enable slashes in Struts 2 action names. I've put this in my config file:
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.action.extension" value=","/>
<constant name="struts.multipart.maxSize" value="2147483648" />
<constant name="struts.enable.SlashesInActionNames" value="true"/>
<package name="myApp" extends="struts-default">
<action name="home" class="net.myapp.actions.HomeAction" method="execute">
<result name="landing">/landing.jsp</result>
</action>
<action name="/ajax/foo" class="net.myApp.actions.ajax.FooAction" method="execute">
<result name="success">/foo.jsp</result>
</action>
</package>
</struts>
When I go to just the homepage of this app, e.g http://localhost:8034/myApp, I see the homepage correctly. But if I visit http://localhost:8034/myApp/ajax/foo, I get the error: There is no Action mapped for action name ajax/foo. even though I have described it above as the 2nd action.
What am I doing wrong?
I'd say you need a namespace as well, so ajax would be the namespace in your case:
<package name="myApp" extends="struts-default" namespace="/ajax">
<action name="foo" class="net.myApp.actions.ajax.FooAction" method="execute">
<result name="success">/foo.jsp</result>
</action>
</package>
Note that you could use slashes in your action names, e.g. foo/bar, but it's not advisable, since some plugins (e.g. the conversation plugin) might have difficulties to determine the namespace and action from a string like /ajax/foo/bar.
Btw, the error message says There is no Action mapped for action name ajax/foo., i.e. struts looks for an action named ajax/foo but you only have an action /ajax/foo.

Struts 2 action method and struts.convention.result.path not working

I have problem with Struts2 action method and struts.convention.result.path
Here is my struts.xml
<struts>
<constant name="struts.action.extension" value="" />
<constant name="struts.action.excludePattern" value="/.*\.(html|jsp),/static/.*"/>
<constant name="struts.convention.result.path" value="/WEB-INF/pages/" />
<package name="user" namespace="/user" extends="struts-default">
<action name="login" class="loginAction" method="login">
<result name="success">login.jsp</result>
</action>
</package>
<struts>
When I run url "localhost:8080/venus/user/login". It display error "HTTP Status 404 - /venus/user/login.jsp"
If I change login() method to execute() method, it works.
Or if I change to <result name="success">/WEB-INF/pages/login.jsp</result>, it works.
Can anyone explain and teach me how use action method with result path config in xml?
Thank you very much!
You should specify the absolute path name.
<result name="success">/login.jsp</result>
When using Convention plugin, xml configuration isn't needed:
com.mycompany.actions.user -> namespaces "user"
LoginAction -> login.action
LoginAction#execute -> success -> user/login.jsp
LoginAction#login -> success -> user/login(-login|-success).jsp

Struts 2 ajax validation unable to find interceptor class jsonValidationWorkflowStack

I'm trying to implement ajax validation in my Struts 2 application. I have included struts2-json-plugin in the build path. Whenever I start the server in Eclipse, I get the following error:
Unable to find interceptor class referenced by ref-name
jsonValidationWorkflowStack - interceptor-ref -
file:/C:/path/struts.xml:15:60
This is what my struts.xml looks like:
<struts>
<constant name="struts.url.includeParams" value="all" />
<constant name="struts.devMode" value="true" />
<package name="default" extends="struts-default">
<action name="submitForm" class="action.FormAction" >
<interceptor-ref name="jsonValidationWorkflowStack"/>
<result>results.jsp</result>
<result name="input">index.jsp</result>
<result name="error">index.jsp</result>
</action>
</package>
</struts>
Why is this happening? I'm following the official struts2 ajax validation tutorial at.
You need to extend the "json-default" package.
The "struts-default" package doesn't know about the "jsonValidationWorkflowStack".

struts2.xml - can't include other .xml file

I am using struts2, for that my struts.xml file contains code like :
<?xml version="1.0" encoding="UTF-8" ?>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<include file="strutsAuthentication.xml"/>
<package name="default" extends="struts-default">
<interceptors>
<interceptor-stack name="crudStack">
<interceptor-ref name="checkbox" />
<interceptor-ref name="params" />
<interceptor-ref name="static-params" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
</package>
And i have specified all the required actions inside the strutsAuthentication.xml. That code is :
<struts>
<package name="authentication" extends="default" namespace="/authentication">
<action name="saveCountry" class="saveCountryAction">
<interceptor-ref name="defaultStack" />
<result name="success">/savecountry.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
When i am deploying my application into tomcat, it gives me warning that :
WARN (org.apache.struts2.components.Form:308) - No configuration found for the specified action: 'saveCountry' in namespace: ''. Form action defaulting to 'action' attribute's literal value.
It means struts.xml can't include strutsAuthentication.xml. Anyone have a solution ?? Thanx in advance....
Got d solution.... For above problem i was done a mistake in calling the action from jsp page. So namespace name "authentication" should be included at the time of calling the action class. Final solution is : "authentication/saveCountry.action".
I don't know what version of struts2 you're using but if you're using the 2.1.x branch you should look at the convention plugin http://cwiki.apache.org/S2PLUGINS/convention-plugin.html. You can get rid of 99% XML configuration.
As an add note. We should never use "xyz.action" in JSP pages. If we later need or decide to change the url-pattern from .action to .do or .html etc. We have to change all JSP pages. A better approach to compose links is:
Link Text

Categories