Default Redirect using Struts2 - struts2

Currently when you hit the root context of my application Struts2 throws an error:
ex. http://localhost:8080/
returns
HTTP ERROR 404
Problem accessing /. Reason:
There is no Action mapped for namespace / and action name .
Is there a way to do a default redirect in Struts2?

In my app I just do the following to redirect to a chosen action:
<action name="*">
<result type="redirectAction">
<param name="actionName">portal</param>
</result>
</action>
Just make sure you place this as the last action in your struts.xml configuration file and then it will catch everything that couldn't be matched earlier on.
This way the redirect happens within struts2, this is invisible to the user.

You can specify a welcome-file-list in web.xml and specify index.jsp, for example:
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Then in index.jsp, you can put this at the top:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=initLogin.action">
Assuming you have something like this in struts.xml:
<action name="*Login" method="{1}" class="com.abc.LoginAction">
<result name="login">/login.jsp</result>
<result name="register">/register.jsp</result>
<result name="success">/success.jsp</result>
</action>
This will redirect to your LoginAction class with an init action.
So then if I went to http://localhost:8080/MyApp, this is the default action it would go to.

Is there no better thing than the meta refresh? Such as in struts there was a jsp:forward... that seems to not work in struts2. I don't know how much I am comfortable with the meta refresh. And don't know different it is than using any java provided redirect, guess I could use that dispatcher class which maybe in the jsp, not sure though.

Go through the examples in the following link, lot of tutorials are given there, using which you can identify your mistakes..
link, link2

Related

struts 2 redirection (type="redirect-Action" , type="redirect") in xml redirecting to http instead of https

We used SSL on strut-2 project. At multiple places, we used redirection in struts.xml like below in code .
<action name="bo_act_creditNote_Save"
class="com.skilrock.lms.web.accMgmt.common.CreditNoteAtBoAction"
method="doCreditNoteBo">
<result name="success" type="redirect-action">
<param name="actionName">bo_act_creditNote_redirect</param>
</result>
</action>
<action name="bo_act_creditNote_redirect">
<result>
/com/skilrock/lms/web/accMgmt/backOffice/bo_act_creditNote_Success.jsp
</result>
</action>
due to ssl browser show some error that
http://mydomain/com/skil/lms/web/userMgmt/bo_act_creditNote_redirect.action'. This request has been blocked; the content must be served over HTTPS.
And the result page is not coming as transaction completed successfully.
To resolve this issue, we removed redirection and replace with JSP page wherever it is used.
But we want to keep redirection action.

Struts won't pass parameter to jsp file

I have an action which (depending on the result) redirects to a suitable file:
<!-- /web/addaccount -->
<action name="addaccount" class="com.x.y.z.WebCreateAccountAction">
<result name="INVALIDLOGIN">/delete/confirm.jsp?err=SIGNIN</result>
<result name="ERROR">/delete/error.html</result>
</action>
For some reason, when redirecting to delete/confirm.jsp, the parameter erris not passed in. I'm at a loss to why this is happening. Is this an incorrect way of passing params to JSP via Struts?
Was just missing a:
type="redirect"
<result name="INVALIDLOGIN" type="redirect">/delete/confirm.jsp?err=SIGNIN</result>
Note: This is advised against, it would redirect directly to a JSP, which would be considered an S2 anti-pattern. See comments below.

struts 2 and sitemesh localization

i am using struts 2 and sitemesh. I can change locale in my login page without problem just by setting a request parameter named with 'request_locale' parameter. But in all other pages i am using sitemesh for decorating header and footer. And i tried to set same parameter for other pages but no luck. These are some of the other codes that i tried in my Login Action:
request.getSession(false).setAttribute("WW_TRANS_I18N_LOCALE", newLocale);
ActionContext.getContext().setLocale(newLocale);
session.put(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE, newLocale);
When i write out these settings i see everything is ok.
But when i write out
<c:out value="${pageContext.request.locale.language}"/>
it is always showing browsers Accept-Language and it doesnt make any localization.
How can i make localization to work with sitemesh?
I tried to redirect from login action to an action named home with request locale parameter and then this action redirects to index.jsp. Everything is ok now.
And i set default action as home action so when user enters root page from address bar it is activing home action so i18n interceptor and intercoptors are becaming active.
This is login.action in struts.xml:
<action name="login" class="wateron.login.LoginAction" >
<result type="redirectAction">
<param name="actionName">home?request_locale=${request_locale}</param>
<param name="namespace">/</param>
</result>
</action>
And this is home action in struts.xml :
<package name="default" extends="struts-default" namespace="">
<default-action-ref name="home" />
<action name="home">
<result>/index.jsp</result>
</action>
</package>
Thanks for reference question :
How to use interceptor on the default page?

url links in struts2 tiles gets namespace added on second time after click. How do I stop this?

I am using struts 2, tiles, and namespaces and am having a problem that after I click a link the menu appends the namespace a second time. I am using the struts tag url with an action and a namespace. When the page is first displayed, the links in the menu are correct land have the namespace before the action. After I click on one of the links, the page redisplays and although the source looks okay, when I hover over it firefox shows the url with the namespace in there twice. I.E.
localhost/ar/customermaint becomes localhost/ar/ar/customermaint. If I have clicked on a link that has a different namespace such as "ss" first then it becomes localhost/ss/ar/customermaint.
any idea what I'm doing wrong? Or is it a problem with tiles and namespaces.
I had faced this issue before. Each time when the action is called, the namespace gets appended in the URL and it looked ugly
Example: http://localhost:8080/RmAirlines/user/user/user/user/user/login for calling the action login from a namespace user each time
Setting the namespace to "/" isn't an ideal solution either.
Solution: Suppose the namespace of the package is "/user" and there's an action named "login" inside it (in your struts.xml). Then where ever you call the action, refer it as action="/user/login" (or action="/user/login.action") - i.e. putting a "/" before the namespace will save your day!
Example:
struts.xml
<package name="userManagement" namespace="/user" extends="struts-default">
<action name="login" class="com.rm.airlines.action.Login">
<result name="success">/user.jsp</result>
<result name="login">/login.jsp</result>
</action>
</package>
login.jsp
<s:form action="/user/login">
<s:textfield label="Email" key="email" />
<s:password label="Password" key="password" />
<s:submit />
</s:form>
To avoid this, always follow a simple principle.
For all namespace declaration, use a slash "/" followed by the namespace name.
In this way, it will not append the earlier namespace in new url.
What struts assume, if you don't specify "/" in new namespace, it tries to find it in currently used namespace. If you specify "/" before namespace name, it takes it as a root namespace.
Example:-
<package name="default" namespace="/nsp" extends="struts-default">
<action name="validate" class="login.LoginAction">
<result name="success">/home.jsp</result>
<result name="login">/login.jsp</result>
</action>
</package>
<package name="cricket" namespace="/cricket" extends="struts-default">
<action name="findcaptain" class="cricket.CaptainAction">
<result>/showCaptain.jsp</result>
</action>
</package>
Look in each of my package declaration, I am using namespace name prefixed by a slash. i.e. /nsp and /cricket). And that's how we could avoid this namespace appending issue.

Removing convention.annotation - replace with config in struts.xml

I'm having an issue removing the #Action and #Result Convention plugin annotations from an action and replacing them with the equivalent config in struts.xml.
package com.microed.cars.web;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import com.opensymphony.xwork2.ActionSupport;
public class HomeAction extends ActionSupport {
#Action(results = {
#Result(location = "/jsp/home.jsp")
})
#Override
public String execute() throws Exception {
return super.execute();
}
}
When these annotations are there, I can successfully access localhost:port/context/home.action
When I remove the annotations I get 'no result defined for action..... ' struts error, despite there being a 'capture all' result in struts.xml - the entire struts.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<constant name="struts.devMode" value="true"/>
<constant name="struts.convention.package.locators" value="web"/>
<constant name="struts.convention.default.parent.package" value="beetroot"/>
<package name="beetroot" extends="json-default">
<action name="home" class="homeAction">
<result>/jsp/home.jsp</result>
</action>
<action name="cars" class="baseCarsAction">
<result name="input" type="json">
<param name="root">autoResults</param>
/jsp/home.jsp
</result>
</action>
</package>
</struts>
It extends json-default because I need the json result type for an autocomplete function.
I don't know why it's not picking up the action mapping for the homeAction class. I know struts.xml is being read because if I remove the action mapping "cars" then the autocomplete is disabled (but this needs the annotations which I'm trying to remove in order to validate this).
I know that 'no result defined' is a simple error, usually caused by spelling/capitalization errors but this is definitely not the case here, it's simply seems to be ignoring the whole "home" action mapping.
When stepping through DefaultActionInvocation.createResult, there are no 'results' at all for it to try to match against.
As it stands the cars action declaration isn't valid (nor does it make sense, IMO):
<action name="cars" class="baseCarsAction">
<result name="input" type="json">
<param name="root">autoResults</param>
<param name="location">/jsp/home.jsp</param>
</result>
</action>
That said: if it's a JSON result, a JSP isn't helpful, and it'll be ignored (or downright rejected, I'm not sure if it's an error or not). A single result will be either JSON, or HTML.
Turn logging up to DEBUG level to catch startup errors to narrow the range of possible causes.
If baseAction is configured in your Spring config file (which is unnecessary if you're using Spring annotations for injection) the configuration for the home action is valid.
I'd be wary of deploying the convention plugin if you're not actually using it: it changes how actions are mapped; it may have an impact on the surrounding application and cause problems. Stick with one or the other, avoid both–it makes it harder to reason about the source of application behavior.
Unrelated, but I recommend putting JSP pages under /WEB-INF to disallow direct client access.

Resources