Reputation: 971
I am displaying a list in my JSP as shown below:
<%@page contentType="text/html;charset=UTF-8"language="java"pageEncoding="UTF-8"%>
<%@taglib prefix="s"uri="/struts-tags"%>
<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>xxx</title>
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<s:form name="tableForm"method="post">
<th>
<s:submit action="verify" key="Add"></s:submit>
</th>
<s:hidden name="propagateList" value="%{formList}"/>
<table border="1">
<tr>
<th >ID</th>
<th>Name</th>
<th>Status</th>
<th>Type</th>
<th>System</th>
</tr>
<s:iterator value="formList">
<tr>
<td><s:checkbox name="checked" fieldValue="%{#attr.ID}" theme="simple" ></s:checkbox>
</td>
<td><s:property value="NAME"/></td>
<td><s:property value="STATUS"/></td>
<td><s:property value="TYPE"/></td>
<td><s:property value="UNIT"/></td>
</tr>
</s:iterator>
</table>
</s:form>
</body>
</html>
Here I want to pass the list formList to another action when I click on Add button without having to hit the database to fetch the list formList once again.
I tried using <s:hidden name="propagateList" value="%{formList}"/>
but it does not work.
This list contains more than 1000 records , so is there any way to pass this list from the jsp to another action in Struts 2 without using session?
Upvotes: 3
Views: 6347
Reputation: 50203
To answer the question "how to pass a List from ActionA to ActionB without using the Session":
in case of a List<String>
:
<s:iterator value="formList" status="row">
<s:hidden name="formList[%{#row.index}]" />
</s:iterator>
This will iterate through your whole List, and will generate an <s:hidden/>
element for every element of the List; this way, you can pass an un-altered List from one Action to another.
in case of a List<Object>
, where the object is that you've posted in the page:
<s:iterator value="formList" status="row">
<s:hidden name="formList[%{#row.index}].id" />
<s:hidden name="formList[%{#row.index}].name" />
<s:hidden name="formList[%{#row.index}].status" />
<s:hidden name="formList[%{#row.index}].type" />
<s:hidden name="formList[%{#row.index}].unit" />
</s:iterator>
Exactly as before, this will iterate through your whole List, generating five elements for every object of the List.
Using this concept, you can alter the List by using interactive tags (textfield, select, etc) instead of read-only tags (hidden, property etc):
<s:iterator value="formList" status="row">
<s:hidden name="formList[%{#row.index}].id" />
<s:textfield name="formList[%{#row.index}].name" value="name" />
<s:hidden name="formList[%{#row.index}].status" />
<s:property value="status" />
<s:textfield name="formList[%{#row.index}].type" value="type" />
<s:textfield name="formList[%{#row.index}].unit" value="unit" />
</s:iterator>
Of course your List will be vulnerable to client-side changes, every user able to press F12 will be able to modify your List, then you should be careful.
You could, for example, put only the ID**s in the **session, inject the List in the JSP, then when receiving the data back, match the *ID*s of List coming from the page with the *ID*s you have in Session, for checking the integrity of the data posted (no new IDs, no double IDs etc)
Upvotes: 5
Reputation: 61148
The reason your code isn't working is because
<s:hidden name="propagateList" value="%{formList}"/>
Doesn't do what you think it does.
This sets a hidden field on the HTML page called propagateList
to the value of formList.toString()
. This is obviously not useful.
You need to set is as CSV or JSON or some serialized from and then deserialize it when is sent back by the client.
There seems to be client/sever side confusion.
First you get the formlist
from the db and use it to render your page. This is an HTML page, it is sent to the client.
The client renders the HTML with your formList
and the does something, clicks add
for example.
The result of the add is that the client sends a POST request back to the server with the data.
Do you really think it is more efficient to send 1000 values back to the server in serialized from and then deserialize them back into a List
rather than hit the db? For one thing it means that a POST request which should be very small becomes rather large.
Use a Session
or maybe cache it locally in some sort of static
cache.
Upvotes: 2