I'm working on a little project which uses Struts 1.3 and I encountered the following problem.
After some business logic takes place in an Action i want to forward the control to another Action which is mapped in struts-config.xml.
Usually this is the way I'm solving this:
struts-config.xml
<action path="/boardCreate" type="com.example.BoardCreateAction" name="BoardCreateForm" input="/board.jsp">
<forward name="success" path="/board.do" redirect="true" />
</action>
Java action class
return mapping.findForward("success");
This will take make a redirect to the board.do action which is also mapped there.
My problem is that I want to redirect the control to something like:
<forward name="success" path="/board.do?id=1" redirect="true" />
Notice the id=1 parameter. Is this any other way except rebuilding my own action forward for this? I can't find any documentation debating this matter. Thanks!
ActionRedirect redirect = new ActionRedirect(mapping.findForward("success"));
redirect.addParameter("id", theId);
return redirect;
See http://tool.oschina.net/uploads/apidocs/struts-1.3.10/org/apache/struts/action/ActionRedirect.html
Related
I'm learning struts 1, yes, the old one.
Is it possible to use an Action (Dispatch Action for example) without a FormBean?
I know that is possible to use a FowardAction, but I want to use a DispatchAction because I need to use a Controller, but I don't need a FormBean, I'll get information from the query string.
Yes, you can do it like this
<action-mappings>
<action path="/myAction" name="myAction" scope="request" type="com.example.app.action.MyAction">
</action>
</action-mappings>
I use the Struts2 framework to create a webapp. I have an interceptor that should have different behaviour depending on which action is invoked. For example, a login interceptor that should always allow some actions to execute, but it should block other actions if the user is not yet logged in.
The way I solve this now is by manually checking the name (and/or namespace) of the action in the interceptor, and determine my behaviour based on that. The downside of this "hardcocded" logic is that it is hard to maintain if I edit my struts.xml file, and it is also not obvious what is going on for other developers.
I would like to know if these is some way to add 'metadata' INSIDE the struts.xml file (or other file?) to "mark" certain actions as being certain "type". For example, something like this:
Struts.xml
<action name="loginPage" types="login, user, viewpage" class="login.controller.LoginPage">
<result name="success">/login/jsp/Login.jsp</result>
</action>
And then in my interceptor class:
#Override
public String intercept(ActionInvocation invocation)
throws Exception
{
Set<String> actionTypes = invocation.getInvocationContext().getTypes();
if(actionTypes.contains("login")
{
doSomething();
}
else
{
doSomethingElse();
}
}
Is this possible, or is the hardcoded parsing of name(space) the only way?
Obviously you can't do that because the DTD won't allow you.
Another good example of the XY problem:
The XY problem is asking about your attempted solution rather than your actual problem.
That is, you are trying to solve problem X, and you think solution Y would work, but instead of asking about X when you run into trouble,
you ask about Y.
What you really need is to define a group of actions running free, and other groups running under login control.
For this, you can manually include the Interceptor in each single action (useful when using the Convention plugin, a waste of time otherwise), or configuring the actions logically in the struts.xml.
The <package> is your friend here: define two (or more) packages, one running with the default settings, the other running your custom Interceptor for each action of the package:
<package name="unsecure-package" namespace="/unsecure" extends="struts-default">
<action name="login" class="org.foo.bar.actions.LoginAction">
...
</action>
<action name="askHelp" class="org.foo.bar.actions.AskHelpAction">
...
</action>
</package>
<package name="secure-package" namespace="/secure" extends="struts-default">
<interceptors>
<interceptor name="authInterceptor"
class="org.foo.bar.interceptor.AuthInterceptor"/>
<interceptor-stack name="securedStack">
<interceptor-ref name="authInterceptor"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="securedStack"/>
<action name="write" class="org.foo.bar.actions.WriteAction">
...
</action>
<action name="delete" class="org.foo.bar.actions.DeleteAction">
...
</action>
</package>
This way every time you or somebody else will add an Action in struts.xml, it will just need to drop it in the right package, and it will work automatically.
It's better to keep the Interceptor action-agnostic whenever possible ;)
I'm developing a simple virtual store for an university project. I'm using struts 1.3. My problem is that I have this:
<action name="ComprarMaisForm" path="/ComprarMais" scope="session" type="com.myapp.struts.ComprarMaisAction">
<forward name="pagar" path="/pago.jsp"/>
<forward name="eliminar" path="/vistaCarrito.jsp"/>
<forward name="comprarmais" path="/index.jsp"/>
</action>
I want to have several actions instead of one. How can I do?
For different type of actions you have to specify different action mappings with different 'paths'
<action path="/goto1" ...> .. </action>
<action path="/goto2" ...> .. </action>
Anyways If You want to have several actions with same name (form-bean name) scope type and forward mappings (probably silly ques), You need the SAME action, just give same action name wherever you want to use it.
If any 1 parameter is different you need to specify different <action/> mappings.
In struts-config I have action like this :
<action
path="/action/basket"
type="com.xxx.BasketAction"
name="basketForm"
scope="session"
unknown="false"
validate="false"
>
<forward
name="displayItems"
path="EshelfItems"
redirect="false"
/>
<forward
name="displayItems-redirect"
path="/action/basket.do?fn=display"
redirect="true"
/>
<forward
name="displayBasket"
path="/basket.jsp"
redirect="false"
/>
</action>
Where I can find the mapping for /action/basket.do?fn=display ?
According to http://struts.apache.org/1.x/faqs/works.html :
In the framework configuration file(s), you associate paths with the
controller components of your application, known as Action classes
(i.e. "login" ==> LoginAction class). This tells the ActionServlet
that for the incoming request 'http://myhost/myapp/login.do' it should
invoke your controller component, LoginAction.
Note the extension .do in this URL. The extension causes your
container (i.e. Tomcat) to call the ActionServlet, which sees the word
"login" as the thing you want to do. The configuration is referenced,
and your LoginAction is executed.
Check your BasketAction class where the fn=display request parameter is checked.
If you can't find the action class for a given mapping then debugging your
RequestProcessor's process method can be also useful.
Ya your question is not clear..
When you hit /action/basket.do?fn=display its going to use the following mapping in your struts config.
<action
path="/action/basket"
And then it will execute
com.xxx.BasketAction
and in that class if you want you can read the param fn=display and then do a forward and that will work as mapped in <forward>...</forward> mapping of your struts config
I have the following actions defined in my struts.xml
<action name="Search" method="prepareLookUpvalues" class="com.mycompany.actions.FrSearchAction">
<result name="success" type="tiles">search.layout</result>
</action>
<action name="List" class="com.mycompany.actions.FrSearchAction">
<result name="success" type="tiles">results.layout</result>
<result name="input" type="tiles">search.layout</result>
</action>
<action name="SearchDetails" class="com.mycompany.actions.FrSearchDetailsAction">
<result name="success" type="tiles">details.layout</result>
</action>
<action name="Logoff" class="com.mycompany.actions.LogoffAction" >
<result name="success" type="tiles">logoff.layout</result>
</action>
Assuming that a user goes directly to my page home http://localhost:8080/fr/Search.action everything works OK, but it has been discovered hat some users are accessing http://localhost:8080/fr/List.action directly without first going to the search page which is causing problems.
When a user goes to the search page and enters criteria and submits, it is only then that the "List" action should be called via the struts form's action attribute. I basically want to stop users from being able to access the "List", "SearchDetails", and "Logoff" actions directly unless those actions are invoked from my JSPs or code.
I'm new to maintaining/developing Struts2 applications and I haven't found clear answers to this. Any suggestions would be greatly appreciated!
There's a few details missing so the answer will be a bit vague, but the list action probably pulls values from a form submission to search? Or pulls state from session? Or...?
Anyways, however that may be stored, simply check and then redirect the user to Search if the state is not set as expected.
For details on doing redirects in struts2, see, for e.g. http://www.roseindia.net/struts/struts2/actions/struts-2-redirect-action.shtml
This isn't an elegant solution but you could try checking for the referer to see who called the action. You action class will need to implement ServletRequestAware.
String referrer = request.getHeader("referer");
if (referrer.equals("http://localhost:8080/fr/Search.action")) {
// do the action
} else {
// handle unwanted access
}
Remember that the referer is a client-controlled value and can be spoofed or removed.