How to make fileUpload parameters dynamic in Struts 2 - java

In a Struts 2 application we use fileUpload interceptor to get file from the user.
The fileUpload has some configurations maximumSize , allowedTypes , allowedExtensions that can be used as:
<interceptor-ref name="fileUpload">
<param name="maximumSize">200000</param>
<param name="allowedTypes">text/plain</param>
<param name="allowedExtensions">txt</param>
</interceptor-ref>
Is it possible to make these parameters dynamic !?
For example :
<param name="maximumSize">${maxsize}</param>
and let the action set its max file size.

It's not possible to make these parameters dynamic. But at runtime when interceptor is invoked you can get the value dynamically
String maxsize = TextParseUtil.translateVariables(maximumSize, actionInvocation.getStack());
The action is invoked after interceptors chain, so it can't set the value. However you can translate the value before chained result.

Related

I18n redirection issue in struts2 web application

In my application Locale is dynamically selected by user from login page and I am saving selected locale in Cookie.
I am facing I18n related problem in case of redirection in my web application.
When I redirect a page by URL by appending current locale then my application language remains same as selected language(i.e working fine in this case), but when I redirect to next page by struts redirection defined in struts.xml file the locale changes to the default value(English in my case).
For example:
In case of- <result name="success" type="redirect"> , locale changes to default one.
In case I remove type=redirect then its working fine but my form will be submitted two times.
So is there any way to append locale to struts redirection at runtime?
Here is one of my interceptor stack:
<interceptor-stack name="sessionValidateStack">
<interceptor-ref name="auditTrail"></interceptor-ref>
<interceptor-ref name="sessionCheck"></interceptor-ref>
<interceptor-ref name="service">
<param name="code">DG</param>
<param name="interfaceType">WEB</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="expHandler"></interceptor-ref>
</interceptor-stack>
Add request_locale=<your_language_key> in your parameters
Use redirect-action instead of redirect in action result type because in case of redirect action,control jumps to the different action(in same or other package).
Please refer link for the difference between redirect and redirect type result type.

Struts2 pass parameters to action in different webapp

I use Struts 2.3.16.3. I want an action from webapp 1 to pass parameters to an action in webapp 2. In the struts.xml of webapp 1 I define the following result:
<result name="success" type="redirect">
<param name="location">http://localhost:8080/Webapp2/index.action</param>
<param name="testParam">testValue</param>
</result>
I expect my browser to redirect me to this webpage (a page in webapp2) when the result equals 'success':
http://localhost:8080/Webapp2/index.action?testParam=testValue
However, my browser takes me to:
http://localhost:8080/Webapp2/index.action
completely ignoring the parameter.
If I change my result to have everything inside the location param then it works, but you can see this gets very clunky with multiple params:
<result name="success" type="redirect">
<param name="location">http://localhost:8080/Webapp2/index.action?testParam=${testValue}</param>
</result>
This correctly redirects my browser to the url:
http://localhost:8080/Webapp2/index.action?testParam=testValue
Why does the first method not work?
If the location starts with http:, https:, mailto:, file:, ftp: then it's used as a final location to redirect using response.sendRedirect(). Parameters in the result using <param> tag in this case are ignored.

Setting a string parameter inside struts.xml action from a properties file

I've been trying to implement an action which allows the user to download a file with a specific filename. This filename is set by passing the action a parameter through struts.xml this way:
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">input_document</param>
<param name="contentDisposition">attachment;filename=foo.bar</param>
<param name="bufferSize">1024</param>
</result>
I have omitted the rest of the code as I just want to focus on this:
<param name="contentDisposition">attachment;filename=foo.bar</param>
That way it works perfectly and lets you download the foo file with .bar extension.
So here's the deal, I was curious to know wether if is it possible to retrieve the extension from a properties file and pass it through the parameter, for example, like this:
<param name="contentDisposition">attachment;filename=foo%{+ getText("EXTENSION_KEY_IN_PROPERTIES_FILE")}</param>
I know that getText("...") won't work but I just want you to understand what I'm searching for.
I'm currently working with some properties files for global parameters and localization stuff so it would be great if I could retrieve this file extension from one of them.
It should work if your action implements TextProvider
<param name="contentDisposition">attachment;filename=foo${getText('EXTENSION_KEY_IN_PROPERTIES_FILE')}</param>

Redirecting to another action with unknown amount of parameters in Struts 2

I have a login action which after successful execution redirects to the previous page (I store the previous page in my session so I can fetch it later). In Struts2, I can find two ways to do this redirection:
<action name="login" class="com.myapp.login.Login">
<result name="redirect" type="redirect">${previousAction.requestURL}</result>
</action>
In this example, the getPreviousAction().getRequestURL() method (this is a selfmade method, its not native to Struts2) will be invoked and this will return the URL of the previous page as intended, for example:
somenamespace/index.action
There is also another type of redirection:
<action name="login" class="com.myapp.login.Login">
<result type="redirectAction">
<param name="actionName">${previousAction.name}</param>
<param name="namespace">/${previousAction.namespace}</param>
</result>
</action>
I want to use this `redirectAction result type because it is much cleaner. But, I have a problem when query parameters are part of the URL. For example:
somenamespace/index.action?name=john&age=50
I know I can add these params hardcoded in my struts.xml, but the problem is my login action should redirect to any previously invoked action, and I do not know beforehand which query parameters the previous actions had. This is different from the typical usecase where you know exactly to which action you're redirecting to
A very bad solution I found was adding every param possible (the collection of all params of all my actions in struts.xml) and then use the option:
<param name="suppressEmptyParameters">true</param>
You can save action name, namespace, and parameters from the ActionMapping.
ActionMapping mapping = ServletActionContext.getActionMapping();
You can also save query string instead of parameter map.
String params = request.getQueryString();
To add parameters dynamically to redirectAction result you should use OGNL in a dynamic parameter.
<param name="actionName">${previousAction.name +'?'+ parameters}</param>
Supposed you have a getter for parameters and initialized it from session where you saved previous query string, action name, and namespace.

How to validate JSON being sent using Struts2 JSON Plugin without throwing exception

Suppose there's a Double variable in an action, and if the value sent in the request body is something like
{"dblField":""}
and the interceptorStack looks like :
<action name="save" class="actions.MyAction" method="save">
<interceptor-ref name="jsonValidationWorkflowStack">
</interceptor-ref>
<!--<interceptor-ref name="loginStack"/>-->
<!-- I've tried using each of the above two separately, but both failed -->
<interceptor-ref name="json">
<param name="enableSMD">true</param>
</interceptor-ref>
<result type="json" name="*">
<param name="excludeProperties">
idIo
</param>
</result>
</action>
Then the action throws a NumberFormatException, which is fine according to the plugin source code here.
But this exception is not handled in the plugin and hence, returns from the action throwing exception, which results in the firing of global-exception-handler.
If the same request was sent using a query-string, ?dblField= then the action returns INPUT.
So, how can I make the json-plugin behave in the same way to return INPUT and set appropriate fieldErrors instead of throwing NumberFormatException and firing the globalExceptionHandler?
You could place exception interceptor before your own interceptor instead of the json interceptor by extending json interceptor and override intercept method where you can catch errors. Then you can either add action errors or rethrow a custom exception which you can map in the action config or globally.
<exception-mapping exception="org.exceptionmapping.CustomException"
result="errorresult"/>
This way you can map all json only interceptor errors with your custom exception.

Categories