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?
Related
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.
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.
In struts2 I am writing an app where I need to make sure that the url redirection works the same whether or not there is a trailing slash at the end.
E.g. example.com/app should behave same way as if user entered example.com/app/. Currently I changed mapping in struts.xml like so -
<struts>
<package name="default" namespace="/" extends="secure">
<interceptors> ... <interceptors>
<action name="app">
<result type="redirectAction">/app/</result>
</action>
</package>
</struts>
and
<struts>
<package name="app" namespace="/app" extends="secure">
<interceptors> ... <interceptors>
<action name="" class="com.example.action.app.LoginAction" method="display">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<interceptor-ref name="basic" />
<result type="redirectAction">home</result>
<result name="display">/jsp/base/content/login/loginForm.jsp</result>
</action>
</package>
</struts>
But this seems hackish since if I go to example.com/app it will show example.com//app/.html in the URL.
Any help appreciated.
Answer was derived in comments under the answer.
Quaternion:
Personally I would write all my urls with out the trailing slash...
and then I would use something external to the application to rewrite
urls as appropriate, perhaps iptables could determine if there is a
trailing slash and if so always strip it.
Mohana Rao SV:
As suggested above follow without tailing slash. And override
StrutsPrepareAndExecuteFilter one of the filter job is from the url it
has to identify the namespace and action name and invoke respective
action. So here remove tailing slash from url.
Quaternion:
In namespace "/" you have an action called app. That is all there is
to it to invoke CONTEXT_ROOT/app (that is what struts2 expects), you
don't ever expect to see a "/" on the end of the url, so you want to
find a method that parses the url before struts2 resolves the mapping.
What you have described only requires something to remove a trailing
"/" if it exists. I'd look to iptables because I've used it before or
some other url rewriter... Mahana would keep it all part of the web
app and use a filter, methods differ but the effect is the same.
Im trying to make it so that once i submit this form i cannot hit the back button, but with the current configuration I cannot even get the page/form to load. I can't seem to figure out why "invalid.token" is always being triggered thus redirecting me to index.jsp no matter what I have the token tag in my form like im supposed to. If i use the "excludeMethods" filter and exclude View then my page loads but I can hit the back button freely so it still does not work properly. I have tried moving the interceptor-ref above and below my noLoginStack but it dosen't make a difference. Based on my debugging my actual java class isn't even being hit, so its failing before then. What am I doing wrong?
My action declaration:
<action name="viewAppointmentLetter" class="edu.ucr.c3.rsummer.controller.instructor.ManageAppointmentLetters">
<interceptor-ref name="noLoginStack"/>
<interceptor-ref name="token" />
<result name="invalid.token">/index.jsp</result>
<result name="error" type="redirectAction">index.do</result>
<result name="input">/instructor/assigned_appts.jsp</result>
<result name="view">/instructor/assigned_appts.jsp</result>
<result type="redirectAction">index.do</result>
</action>
My assigned_appts.jsp:
<s:form action="saveAppointmentLetter" onsubmit="return verifySubmit();">
<s:token name="token" />
.....
</s:form>
If its any clue I always get this in my console
WARN org.apache.struts2.util.TokenHelper - Could not find token name in params.
In struts2 the order of interceptor is very important. you should follow this order.
<interceptor-ref name="token"/>
<interceptor-ref name="noLoginStack"/>
USe TokenSession interceptor.Had to handle result by result name="invalid.token" in struts.xml in specific action.
The page from which your action is generated at that page you have to write <s:token> tag in the header
How can i redirect www.mysite.com/12345 to www.mysite.com/action?id=12345 using struts2?
I use URL rewriting to get these kind of flexible mappings working (though you could probably do it in struts proper, possibly with your own interceptor or something). There's a great little project, urlrewritefilter that gets the job done. In your URL rewriting configuration you'd have a rule like:
<rule>
<from>^/(\d+)$</from>
<to>/action?id=$1</to>
</rule>
Have a look at the manual to see if it is what you are looking for.
<action name="12345">
<result type="redirect-action">
<param name="actionName">action</param>
<param name="id">12345</param>
</result>
</action>
UPDATE
Ok. Based on the comment below.
I have managed something like this in this way in the past. Create a package in struts with a catch all action.
<package name="numbers">
<action name="*" class="my.package.ActionClass" method="urlrewrite">
<result type="redirect-action">
<param name="actionName">${nextpage}</param>
<param name="id">${id}</param>
</result>
</action>
</package>
Then in the urlrewrite method of the action class:
public String urlrewrite(){
//parse the url and determine the ID and the next page
nextpage = "action";
id = "12345";
return SUCCESS;
}
So in calling the action you will have to do like this:
http://www.mysite.com/numbers/12345.action
If you do not want a new package then you can do this in the default package.