Struts2 - See real destination url in browser on action result - url

In Struts2, when returning from a successful action, I want the user browser to show to the user the real url he is navigating into, and not the original call to action. As far as I understand, I cannot use a type="redirect" action because I need to pull the action results from the value stack.
Let's say, for example, if I define an action to save a new element in my db, and then I want to take the user to see the whole list of elements...:
<action name="doSavePage" class="FbPageAdmin" method="doSavePage" >
<result name="input">/pageadmin.jsp</result>
<result name="error">/pageadmin.jsp</result>
<result name="success">/pageList.jsp</result>
</action>
If the action finishes successfully, I want the user to see mysite.com/pageList.jsp, and not mysite.com/doSavePage.action
Is that possible?
Thanks everybody in advance!

Why would you want to have the JSP file name shown?
In any case, I'm not sure I understand; if you want to show a listing of objects after adding one, redirect to the "list" action (and/or method). You should do a redirect after a POST anyway (the post-redirect-get pattern) to avoid resubmitting the same form data on a refresh.
Also, ideally, JSPs should live under /WEB-INF to disallow direct aclient access.

Related

How do you create a Language Selector in Struts 2?

I know I can call a url with the "request_locale" parameter but that won't last long. Maybe storing it in a cookie? Which I don't know how to do.
After many hours of searching I found:
A low of dead links in the apache API
Setting the locale in session attribute "org.apache.struts.action.LOCALE"
... or "request_locale"
... or "request_cookie_locale"
... or "WW_TRANS_I18N_LOCALE"
Setting the locale in ActionContext.getContext()
Something about interceptors that make my application throws exceptions so I don't know if I should pursue...
There's a mix of Struts 1 and Struts 2 in there which is not making things easier...
Here's what I have so far:
In the XML config:
<action name="languageSelection" class="changeSelectionAction">
<result name="input" type="redirect">${redirectUrl}</result>
</action>
I figured I'd use "Input" to go back to the previous page after the user selected a language.
The redirect variable is defined in my Action Class.
In the Web Page:
<webwork:url id="url" action="languageSelection">
<webwork:param name="lang">fr</webwork:param>
</webwork:url>
<webwork:a href="%{url}">French</webwork:a>
This sends "lang=fr" which I can read in my Action Class.
In the Action Class, I have:
HttpServletRequest request = ServletActionContext.getRequest();
String refererUrl = ServletActionContext.getRequest().getHeader("Referer"); // gives me the source page so I can go back to it.
setRedirectUrl(refererUrl);
String[] langs = request.getParameterValues("lang"); // getting the language the user selected
... followed by a lot of garbage that doesn't work and some insults for the compiler that are commented out.
I'm not the best web developer so any basic web advice will be welcome.
You can implement a i18n interceptor which can store your locale in the session or a cookie. See https://struts.apache.org/core-developers/i18n-interceptor.html
<interceptor name="i18nCookie" class="org.apache.struts2.interceptor.I18nInterceptor"/>
<action name="someAction" class="com.examples.SomeAction">
<interceptor-ref name="i18nCookie">
<param name="localeStorage">cookie</param>
</interceptor-ref>
<interceptor-ref name="basicStack"/>
<result name="success">good_result.ftl</result>
</action>
We use the org.apache.struts2.interceptor.I18nInterceptor in our default interceptor stack. After that struts listen to the parameter request_locale and every action that gets a ?request_locale=LANGCODE parameter will change the language for the user. Normally this setting is stored in the session of the user, so make sure user sessions are enabled too.
With the link from #TheSlavMan you can read all the possible options available for this interceptor.
Of course a simple "change language and redirect to a page"-action is possible. You are on the right path, my first guess would be to change the lang-parameter to request_locale.

how to implement global redirect page in struts2

We're using Struts 2 in our web application. There are bunch of action mappings defined already, I want to implement a feature where any Urls starting with /buy and not mapped to any of the existing action mappings e.g. /buy/new or buy/old should be redirected to buy/index action. For example if someone is trying to go to /buy/bla1 or /buy/bla2 or buy/bla1/bla2/bla3 should go to buy/index.
Define the following action in your /buy package:
<action name="*">
<result type="redirectAction">index</result>
</action>
Alternatively you can just use:
<default-action-ref name="index" />
But then you will get no redirect. Instead the index page will show under the nonexisting address.
You also need to set the following parameter in your struts.properties:
struts.action.extension = action,,
You can add other extensions to the parameter, but as far as i know there is no wildcard for all extensions. The blank string covers directories like /buy/bla but /buy/bla.x won't be covered and will produce a 404 error unless you add x to the list of extensions.
If this is not good enough you might be better off solving this by using redirect rules in the webserver.
You can use default action reference and provide a JSP success path to it.
If any unmatched action is received then it will call the given action and forward it to the result JSP page.

How to disable struts 2 validation before form submission?

I'm doing a project with struts2, Hibernate.
I want struts to validate my form. I have added a MyAction-validation.xml and it works fairly well. (I say fairly well because it doesn't validate on the client side. I have set the validate attribute of the <s:form/> tag to true)
First it provided me some errors and googling it I got that I should add a result with input name. So now I have a result with input name in my action without understanding well how it works and why.
My action returns a plain form when it is called by myAction.action url and when the form is submitted the data goes directly to the action parameters and saved in database. Then a filled form will be shown with a success message. The form fields should be validated upon the submission. But they are validated whenever the action is invoked. I tried #SkipValidation annotation but it cancels the validation completely. Even when I call the validate method in the execute method it doesn't run. I tested it by some System.out.println lines. My action definition in the struts.xml is the following:
<action name="ShowAddItemPage" class="action.clerk.ShowAddItemPage">
<result name="success" type="tiles">addItem</result>
<result name="generalError" type="tiles">clerkGeneralError</result>
<result name="input" type="tiles">addItem</result>
</action>
How can I make the validation work on the client side?
How can I make the validation run only upon the form submission and disable it when there form fields are provided by the application?
What is input result name for and why did I have to add it to the action results?
By setting the validate attribute to true, just like you said.
By having a different action for displaying the form, or by creatong an interceptor that skips validation on a GET (that's what I used to do), etc.
"input" is the result used when validation fails, although you can change it. If validation fails (and by default, type conversion failures as well) it has to go somewhere, and the "input" result is where.

Default result in struts2

Im wondering if it's possible to set a default result that would apply to every action in struts2.
For example to say that result "FOO" will always redirect to action BAR or to jsp "BAR.jsp" instead of adding <result name="FOO">xxx</result> to every action I define ...
That would help me to create a generic error page
Thanks
Yes, you can set global results for a package.
<global-results>
<result name="error">/Error.jsp</result>
<result name="invalid.token">/Error.jsp</result>
<result name="login" type="redirectAction">Logon!input</result>
</global-results>
For more details read Result Configuration Page
One quick solution that comes to my mind is global result configuration.Most often, results are nested with the action element. But some results apply to multiple actions. In a secure application, a client might try to access a page without being authorized, and many actions may need access to a "logon" result.
If actions need to share results, a set of global results can be defined for each package. The framework will first look for a local result nested in the action. If a local match is not found, then the global results are checked.
<global-results>
<result name="error">/Error.jsp</result>
<result name="invalid.token">/Error.jsp</result>
<result name="login" type="redirectAction">Logon!input</result>
</global-results>
For more details refer to the official doc
result-configuration

Struts2 dispatch request to another application

I'm using Struts 2.1.8.1. I have a requirement to embed some pages from another server on my own app, so the users will access to them through my application, without accessing directly the other server. My idea is to have a package definition for that, so any access to that package would be redirected to the internal server.
<package name="eco-marketing" namespace="/marketing" extends="eco-default">
<action name="*">
<result name="success" type="dispatcher">
<param name="location">http://myotherserver:8080/test/{1}</param>
</result>
</action>
</package>
But it does not work, I got a Error 404--Not Found, so I suppouse is not as easy as it sounds. Any ideas on how to do this?
TIA
I'll assume that you are accessing just html, then see: http://download.oracle.com/javase/tutorial/networking/urls/readingWriting.html
I would recommend creating an action in that package to do the work for you, and use the value of the parameter to get the required data.
You probably already know but an iframe in the consumer action will make this easier to use than trying to parse what you need out.
After you have that figured out, if you decide to create a custom result type, please post it back to us here it would be very interesting.
An example of a custom result type can be found here (4th code block from the top): http://siriwardana.blogspot.com/2008/12/creating-custom-result-type-struts-2.html

Resources