How can I acess a map value inside an object with struts2? - java

I have this map inside a class named Code:
class Code{
Map<Field, FieldValue> properties = new HashMap<Field, FieldValue>()
}
And I have a list of codes, but I want to access the map properties values in the browser trough JSON and using Struts2, so I'm trying something like this:
<action name="CodeJSON" method="list" class="codeAction">
<result type="json">
<param name="includeProperties">
^codes\[\d+\]\.properties
</param>
</result>
</action>
I also tried this:
^codes\[\d+\]\.properties\[\d+\]\.key
And other similar things. What am I doing wrong?

Related

How to work with view in Struts 2?

In plain old servlets I can use doGet and doPost methods. Where in doGet i'm forwarding user to some page and in doPost i'm proccessing data entered from the page that I gave. That all happening in one servlet.
But the Struts2 works on Front Controller pattern and instead doGet/doPost I have only execute method. So how can I properly give user some page, so then he can see it, enter data, submit and application as result proccess it in execute ?
From what I know I have two options (example on registration form):
Map page to another url:
<action name="register_display">
<result name="success" type="dispatcher">register.jsp</result>
</action>
<action name="register"
class="magazine.action.client.RegisterClientAction"
method="execute">
<result name="success" type="redirectAction">/index</result>
<result name="error" type="redirectAction">register_display
</result>
</action>
Create whole package named display and place there all view from which POST can be performed:
<package name="display" namespace="/display" extends="struts-default">
<action name="register">
<result name="success" type="dispatcher">register.jsp</result>
</action>
...
</package>
Is there any other options ? Which one is prefered ?
In the standard Struts2 style, an Action class has only one work method, this is the execute method. However, you do not necessary have to follow this. You can define multiple actions in a single Action class.
For example you make a GET request to users, which is handled in the default execute method of UsersAction.
#Override
public String execute() {
// fetch the list of users
return SUCCESS;
}
Let's suppose you would like to add a new user in this same action, by POSTing to user_add. So you define an add method:
public String add() {
// add the user
return SUCCESS;
}
The struts.xml would look similar to this:
<package name="users" extends="defaultPackage">
<action name="users" class="com.example.UsersAction">
<result>users.jsp</result>
</action>
<action name="user_add" class="com.example.UsersAction" method="add">
<result type="redirect">users</result>
</action>
</package>
In your scenario, you would render your page, which the user should see after the run of the (maybe empty) execute method. Then, you would make the post request, which would be mapped to the other method of the Action class.

Accessing struts action result's parameters in an interceptor

I'm using struts and spring integrated frameworks in my project. I have an interceptor before every struts action call. I need to access my action name and am doing so with the following piece of code:
actionInvocation.getProxy().getActionName();
and my struts action in struts.xml is :
<action name="uploadDocument" class="commonAction" method="uploadDocument">
<interceptor-ref name="sessionStack"/><interceptor-ref name="cachingStack"/>
<interceptor-ref name="basicStack"/>
<result name="success" type="stream">
<param name="contentType">text/html</param>
<param name="result">inputStream</param>
</result>
</action>
I need to access the parameters under the result tag. Is that possible?
Sure.
You can read the result configuration in a ResultConfig object, like described here, that will expose a Map of its params, like shown by the source code.
Something like:
// Get the action configuration defined in struts.xml
ActionConfig config = invocation.getProxy().getConfig();
// Get the SUCCESS result configured for that Action
ResultConfig success = config.getResults().get("success");
// Iterate the Params, friendly printing :)
for (Map.Entry<String, String> entry : success.getParams().entrySet()) {
System.out.println("<param name=\""
+ entry.getKey()
+ "\">"
+ entry.getValue()
+ "</param>");
}

Dynamically set value to static parameter in Struts 2

I was wondering, is it possible to dynamically set value to static parameter
<action name="TestApp_*" class="test.TestApp" method="{1}">
<param name="app_Id">Dynamic value here</param>
<result name="input">WEB-INF/jsp/test/testView.jsp</result>
</action>
I tried
<action name="TestApp_*" class="test.TestApp" method="{1}">
<param name="app_Id">${app_Id}</param>
<result name="input">WEB-INF/jsp/test/testView.jsp</result>
</action>
Not working. It shows ${app_Id} as regular text.
Note sure what exactly you mean by It shows ${app_Id} as regular text.Struts2 provide this flexibility where you can set param values dynamically.
All you need to set these values in your action class and you are all set to use them as a place holder.
public class MyAction extends ActionSupport {
private int app_Id;
public String execute() {
// you execute logic
this.app_Id= 123;
return SUCCESS;
}
// getter and setter for app_Id
}
And you can use this app_Id in your result configuration
<action name="TestApp_*" class="test.TestApp" method="{1}">
<param name="app_Id">${app_Id}</param>
<result name="input">WEB-INF/jsp/test/testView.jsp</result>
</action>
you can get more details parameters-in-configuration-results
You probably have written (erroneusly) the getter by hand, instead of letting the IDE do it for you.
A variable app_Id; must have a getter getApp_Id(), while you could have something like getapp_Id() or get_app_Id()... but how are we supposed to know it if you don't post your Action code ?!
Also, consider to change your variables (from now on) to respect the convention, that wants them camelCased, instead that underscore-separated... then appId for the variable and getAppId() for the getter.
try to do it like this way..
<result type="redirect">
<param name="location">WEB-INF/jsp/test/testView.jsp</param>
<param name="inputName">app_Id</param>
</result>
in the jsp page you can directly use this value like
<s:properties value="app_Id">
try this.
Look at the staticParams interceptor.
This interceptor populates the action with the static parameters defined in the action configuration. If the action implements Parameterizable, a map of the static parameters will be also be passed directly to the action. The static params will be added to the request params map, unless merge is set to false.
Parameters are typically defined with <param> elements within struts.xml.
It shows how to configure this interceptor to your action configuration.
For example:
<action name="someAction" class="com.examples.SomeAction">
<interceptor-ref name="defaultStack">
<param name="staticParams.parse">true</param>
<param name="staticParams.overwrite">false</param>
</interceptor-ref>
<param name="num">${numValue}</param>
<result name="success">good_result.ftl</result>
</action>
This enables the interceptor to parse parameter values for OGNL expression from the action configuration.

Using struts2 to redirect with dynamic parameters not working

I'm having an issue while trying to redirect mapping with dynamic parameters.
The way I'm mapping in Struts2:
<action name="Delete" class="templateLalaAction" method="remove">
<result name="success" type="redirect-action">
<param name="actionName">LalaTemplatesDisplay</param>
<param name="buId">${buId}</param>
</result>
<result name="failure" type="redirect-action">
LalaTemplatesDisplay
</result>
</action>
The method "remove" in the action:
remove() {
putRequestAttribute("buId",Long.valueOf("1111"));
return SUCCESS;
}
if I do this, I'm setting the buId=1111, but when I run the app, the url ends with buId= (it's empty), i.e., no parameter is being passed.
if I comment the putRequestAttribute method, and set struts passing buId parameter as a static value:
<action name="Delete" class="templateLalaAction" method="remove">
<result name="success" type="redirect-action">
<param name="actionName">LalaTemplatesDisplay</param>
<param name="buId">1111</param>
</result>
<result name="failure" type="redirect-action">
LalaTemplatesDisplay
</result>
</action>
It works and the url ends with buId=1111.
I also read this question where the accepted answer teaches us to do the same I did, but if we read the comments the user did, we'll see he has the same problems I have. What am I possibly doing wrong?
Inside your method just assign buId variable and you need getter/setters for it in your action class.
public String remove() {
buId = 1111l;
return SUCCESS;
}
Also you are using old syntax for redirect-action, use camel case redirectAction.

Struts2 returns empty JSON in my AJAX call

I am struggling to get the JSON response from my Struts2 Action class, I think i am missing something. The following set up I have in my Project.
in my module level action definition , The configuration looks like :
<package name="customer" namespace="/" extends="struts-default,json-default">
<action name="getCustomer" method="getCustomerBusiness" class="CustomerAction">
<result type="json"/>
</action>
</package>
in my Struts.xml I have
<result-types>
<result-type name="json" class="org.apache.struts2.json.JSONResult"/>
</result-types>
<interceptors>
<interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/>
</interceptors>
In My Action Class:
public class CustomerAction extends ActionSupport implements ServletRequestAware,
ServletResponseAware, ModelDriven {
private List<CustomerBean> cpbeanList;
public List<CustomerBean> getCpbeanList() {
return cpbeanList;
}
public void setCpbeanList(List<CustomerBean> cpbeanList) {
this.cpbeanList = cpbeanList;
}
public String getCustomerBusiness() {
cpbeanList = new ArrayList<CustomerPortfolioBean>();
// jsonData = new LinkedHashMap<String, Object>();
CustomerBean cb1 = new CustomerPortfolioBean();
cb1.setBusinessNm("IBM");
cb1.setBusinessAddr("475 Anton Blvd");
cb1.setBusinessPh("00000000");
cb1.setBusinessCity("Costamesa");
cb1.setBusinessStateCd("CA");
c1.setBusinessZip("92704");
similarly cb2, cb3, cb4.
cpbeanList.add(cb1);
cpbeanList.add(cb2);
cpbeanList.add(cb3);
cpbeanList.add(cb4);
return SUCCESS;
}
}
The JSON request http://localhost:8080/customer/getCustomer returns me empty array {} In the firebug ...I am able to see.
Also I am trying the out put as data table input in JQuery. which doesn't have row because of this.
Any one's help is greatly appreciated.
Your action's superclass implements ModelDriven, hence so does your subclass. It's the model that will be serialized as JSON. If the model is empty, there's nothing to be serialized, so you get nothing back.
Your subclass should override getModel() and return the data you want to be serialized to JSON.
Since
The ModelDriven Interceptor pushes the model on top of the ValueStack
The Json Result serializes the whole action
and knowing that
The Json Result has a root parameter that can be configured to restrict the Json serialization to a single element instead of that to the whole action's attributes
The root parameter accepts OGNL
we can make the assumption that it could be instructed to go backwards, to be less restrictive (from a modelDriven point of view), instead of more restrictive as usual.
You could try to do something like
<result type="json">
<param name="root">
[1]
</param>
</result>
or even better (since it is not guaranteed that [1] is the action)
<result type="json">
<param name="root">
#action
</param>
</result>
to discover if it's actually possible to serialize the whole action while maintaining the Model on top of the ValueStack.

Categories