Passing a List from Action class to jsp and From JSP to action class in struts2 - jqgrid

I have a requirement where i am using Struts2 as well as Jqgrid in JSP.
As per my requirement i am getting a list from different action class through interceptor.
I have to pass the list to JSP and from the Jgrid url back to respective action class.
When i am using request.setAttribute and passing the same value as parameter for
jqgrid action class url its working fine
[E.g showExcelGrid.action?LIST='+"<%=request.getAttribute("LIST")%>" but when list is large its not working properly.
Please suggest some ideas.
Thanks

I am not sure how JqGrid work but below describe the way value flow both way
To send List/Map or any other collection backed object from your action class to JSP all you need to create a list property in your action class and provide its getter and setters for this
Sample Action Class
public class SampleAction extends ActionSupport{
private List<String> listForJspPage;
//getter and setter for this list property
public String execute() throws Exception{
listForJspPage=new ArrayList<String>();
listForJspPage=fill this list with values
return SUCCESS;
}
}
with above code when your action will get executed you have listForJspPage in value stack and can be accessed using OGNL
Sample JSP
<s:iterator value="listForJspPage">
// do what ever you want to fo
</s:itertor>
here value="listForJspPage" will be interpreted by S2 as getListForJspPage() in your action class to fetch the values.
For sending the value back to action class we can make sure of the setter method with a little help from OGNL like
<s:iterator value="listForJspPage">
<s:textfield name="listForJspPage['%{id}'].value" value="%{value}" />
</s:itertor>
In this we iterate over the listForJspPage List. On the textfield tag we set the name to "listForJspPage['%{id}'].value", this would result in something that looks like "listForJspPage['1'].value". which further can be seen as
getListForJsppage().get(index).setvalue(out given value);

I know this late, but I found this one today which works.
You can pass the list from one action class to another via jsp using the s:select tag of struts2 as follows:
List<String> formList //getter and setter should be there in both the action classes
<div id="divList" style="display: none;">
<s:select list="formlist" multiple="true" id="selectedList" name="formListList"></s:select>
</div>

Related

#ModelAttribute Display Value Methods (for JSP Variables) Outside of Controller

In our Controllers we have methods for populating some Display Values used by the JSP. Example: the list of US States:
#Controller
#RequestMapping("/myURL")
public class MyController {
//...
// A US State ModelAttribute populator used by JSP
#ModelAttribute("us_states")
public TreeMap<String,String> getStateDisplayValues()
{
// ... Code to populate US states for a dropdown
}
}
In JSP:
<form:select path="state">
<form:options items="${us_states}" />
</form:select>
But a concern came up that the Controller shouldn't have this method, it should go in a different place, like the Model. Maybe we are violating some MVC principle by defining these methods in the Controller.
However when I tried moving these #ModelAttribute methods to my Model object, the JSP stopped working. What is the proper place to put these JSP variables? Do I just create Model fields on top of my "regular" model to support them?
#ModelAttribute only supported for controller classes with #RequestMapping methods, so you can't move to your Model object.
us_states not a JSP variables, its a global variable within the scope of controller associated to Model object while passing to JSP.
I prefer using #ModelAttribute if there is one time static data has to load from database(like states), instead of calling every time or otherwise, you can put the states in Enum and pass it to JSP.

Thymeleaf nested object form binding not generating good input name

I have a following object structure:
public class A{
private int id;
private B objB;
public A(){}
--- setters & getters ---
}
This is my class B:
public class B{
private int id;
private int test;
public B(){}
--- setters & getters ---
}
Im passing an A object to my view and i want to create a form to my B object:
<form id="bForm" th:object=${A.objB} th:action="#{/save}">
<input th:field=*{test} type="text"/>
</form>
However the above code will work it will generate the input name like this: objB.test and for this my controller cannot bind it to a B object.
This is the receiving method in my controller:
#RequestMapping("/save")
#ResponseBody
public String setB(#ModelAttribute("bForm") B b, BindingResult result) {
aService.setB(b);
return "...";
}
How can i set Thymeleaf to name my fields without the prefix so instead of: objB.test just test?
Any help is greatly appreciated.
According to thymeleaf-spring docs:
Values for th:object attributes in form tags must be variable expressions (${...}) specifying only the name of a model attribute, without property navigation. This means that an expression like ${seedStarter} is valid, but ${seedStarter.data} would not be.
Try using a th:with attribute before your form to assign your A.objB variable and, therefore, avoid using property navigation in the th:object attribute.
It seems that to adhere to this requirement you have to set an additional model attribute in your Spring controller's handler method that is handling the initial form rendering. So given that you already have something like this in some part of your code:
model.addAttribute("A", new A());
add another line:
model.addAttribute("bForm", new B());
Keep in mind to keep the model attribute name consistent with the one you had set in #ModelAttribute annotation in your submission request handler you've posted in your question.
Maybe a late answer, but if objectB is inner object of A, then you can bind fields to B as inner object of A and process objectA in your controller.
It would look something like this, but in my case prompt is Arraylist of contained objects here:
<th:block th:each="pr, stat : ${taskExecution.prompt}">
<input type="hidden" id="hiddenName" th:field="*{prompt[__${stat.index}__].name}" th:value="${pr.name}">
<input type="hidden" id="hiddenValue" th:field="*{prompt[__${stat.index}__].value}" th:value="${pr.value}">
</th:block>

Spring form commandName = session attribute

I have many pages with the same form where I bind my object using commandName. I try to put the object to session with name "myObject" and use it for form (commandName = "myObject"). But system throws exception (Neither BindingResult nor plain target object for bean name "myObject").
How can I bind the object to session for any controllers and requests?
That error is typical when your use a form:form tag that targets a command object that is not available in the request.
A good approach is to combine #ModelAttribute annotated method with #SessionAttributes on a Controller that intially forwards to the view that contains the form, something like
#Controller
#SessionAttributes("myObject")
public class FormController {
#ModelAttribute("myObject")
public MyObject createMyObjectBean() {
return new MyObject();
}
...
}
The initally createMyObjectBean will be called with whatever is the first request to the controller methods, but it won't be called on subsequent request as the myObject value will come from session due to #SessionAttributes
just note that for this approach to work, you must have a controller that forwards to the view that contains your form

What is the best way to pass values from jsp to controller in Spring mvc

I have a jsp page that is dynamic configured. By different choice, the page has different components, just like dropdown list, list box and datetime etc. For one choice, the page may have only two dropdown list, and by another choice, the page has more enter field. Each enter field has different name. Even one page has two dropdown lists, the two lists have different names.
Just want to get your suggestion, what is the best way to get all these values to controller in Spring MVC.
I would do it as follows:
JSP: enclose all the input fields (textbox/select/checkbox/radio) in <FORM> tags and set the action attribute of the form to call the Controller.
Controller:
Define a simple Java bean class with attributes corresponding to each of the input field in the form
Accept this class type as a parameter to the method in the controller that will be called upon <FORM> submission and annotate the parameter with #RequestBody.
See Mapping the response body with the #ResponseBody annotation for more details on completing the wiring.
Create a DTO to hold all possible form element
Class MyFormData {
private String name;
private Double salary;
private List<String> hobbies;
......
}
In controller, use #ResponseBody
#RequestMapping(value = "/something", method = RequestMethod.POST)
public void handle(#RequestBody MyFormData formData, Model model) {
...
}
If your UI is so dynamic, you might as well bite the bullet and go for a Javascript solution. Spring MVC will simply receive and return JSON as #RequestBody and #ResponseBody and not worry so much about the fundamental MVC.
JSP can only get you so far in terms of dynamic UI behavior. Once you get comfortable with JQuery and/or AngularJS, you'll never look back.

Data binding without using spring taglib

My html is built without using the spring taglib and now I'd like to bind the parameters of the form to a object in my controller.
Currently my form looks like this
<form>
<input type="text" name="frAccUserMgmt.userName"/>
<input type="password" name="frAccUserMgmt.userPwd"/>
</form>
The relevant part of my object is
Class FrAccUserMgmt {
private String userName;
private Strint userPwd;
// getter and setter
}
My controller is
#RequestMapping("login")
Public ModelAndView doLogin(FrAccUserMgmt frAccUserMgmt) {
//code
}
How do I go about binding it. Currently the binding doesn't happen. I just get an empty object in my code.
You could try including the BindingResult class in the method signature and then see if there are any binding errors:
#RequestMapping("login")
Public ModelAndView doLogin(FrAccUserMgmt frAccUserMgmt, BindingResult result) {
if (result.hasErrors()) {
logger.warn("BindingResult errors: " + result.toString());
}
//code
}
Remove the frAccUserMgmt part from the form field names. Spring will automatically find the command object to bind the request parameters based on the getters and setters defined in the command object.
This can also be done by adding the #ModelAttribute for the parameter bean that should be populated with the request parameters.
As per spring docs
http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-modelattrib-method-args
(16.3.3.8 Using #ModelAttribute on a method argument)
An #ModelAttribute on a method argument indicates the argument should be retrieved from the model. If not present in the model, the argument should be instantiated first and then added to the model. Once present in the model, the argument's fields should be populated from all request parameters that have matching names. This is known as data binding in Spring MVC, a very useful mechanism that saves you from having to parse each form field individually.

Resources