简体   繁体   中英

In Struts2, how do I persist data between 2 actions?

I have a Struts 2 page with 2 DisplayTag tables on there, each having a List<T> . This List<T> is populated in code-behind and can be a couple of thousand entries long. On the page, I can select rows of either of the tables and press a button to move them from one table to the other. This can be done multiple times before finally pressing another button to save the contents of one of the tables in the database. I want to do both of these things in the action through AJAX.

userGroupEditmembers.jsp (apologies for the excess whitespace, remnant of using block selection in eclipse)

<table>
    <tr>
        <td>
            <p class="collectionAlt">
                <s:text name="overview.groupMembers" />
            </p>
            <s:set name="groupMembers" value="groupMembers" scope="request" />
            <display:table name="groupMembers" uid="row" excludedParams="*" cellspacing="1" cellpadding="1">
                <%-- include localized messages for the table's banner --%>                     
                <%@ include file="/jsp/includesstruts2/displayTagBanner.jsp"%> 

                <display:column sortable="false" headerClass="listHeader">
                    <s:checkbox name="groupMemberOids" fieldValue="%{#attr.row.oid}"  theme="simple" />                                                       
                </display:column>                                                               
                <%-- User Name --%>
                <display:column property="userId" titleKey="label.user.userId" headerClass="listHeader" />                                                 

                <%-- User Name --%>
                <display:column property="name" titleKey="label.user.name" headerClass="listHeader" />                                                 

                <%-- Whether the User is archived --%>                                          
                <display:column titleKey="label.user.archived" headerClass="listHeader"         
                    class="iconColumn">                                                         
                    <s:if test="%{#attr.row.archived}">                                         
                        <img src="<s:url value='/images/checkedWarning.gif'/>" border="0" />    
                    </s:if>                                                                     
                </display:column>                                                               
            </display:table>                                                                    
        </td>                                                                                   
        <td>                                                                                    
            <%-- 'Remove Users from Group' button --%>                                          
            <input value="&gt;&gt;" type="button" id="removeUsersButton" /> <br />              
            <br />                                                                              
            <%-- The 'Refresh' button. Used to reload the issueTrackingSystemEditDialog.jsp --%>
            <input value="&lt;&lt;" type="button" id="addUsersButton" />                        
        </td>                                                                                   
        <td>                                                                                    
            <p class="collectionAlt">                                                           
                <s:text name="overview.nonGroupMembers" />                                      
            </p>                                                                                
            <s:set name="nonGroupMembers" value="nonGroupMembers" scope="request" />            

            <display:table name="nonGroupMembers" uid="row" excludedParams="*"                  
                cellspacing="1" cellpadding="1">                                                
                <%-- include localized messages for the table's banner --%>                     
                <%@ include file="/jsp/includesstruts2/displayTagBanner.jsp"%>                  

                <display:column sortable="false" headerClass="listHeader">                      
                    <s:checkbox name="nonGroupMemberOids" fieldValue="%{#attr.row.oid}"         
                        theme="simple" />                                                       
                </display:column>                                                               
                <%-- User Name --%>                                                             
                <display:column property="userId" titleKey="label.user.userId"                  
                    headerClass="listHeader" />                                                 

                <%-- User Name --%>                                                             
                <display:column property="name" titleKey="label.user.name"                      
                    headerClass="listHeader" />                                                 

                <%-- Whether the User is archived --%>                                          
                <display:column titleKey="label.user.archived" headerClass="listHeader"         
                    class="iconColumn">                                                         
                    <s:if test="%{#attr.row.archived}">                                         
                        <img src="<s:url value='/images/checkedWarning.gif'/>" border="0" />    
                    </s:if>                                                                     
                </display:column>                                                               
            </display:table>                                                                    
        </td>                                                                                   
    </tr>                                                                                       
</table>                                                                                        
<s:token />                                                                                     


<s:hidden name="oid" />                                                                         
<s:hidden name="version" />                                                                     
<s:hidden name="groupMembersJson" />                                                            
<s:hidden name="nonGroupMembersJson" />

UserGroupEditMembersAction.java:

private Integer oid;
private Integer version;

private List<UserView> groupMembers;

private List<UserView> nonGroupMembers;

private String groupMembersJson;

private String nonGroupMembersJson;

private Integer[] groupMemberOids;

private Integer[] nonGroupMemberOids;

private Boolean showArchived;

/**
 * method for DisplayUserGroupEdit action.
 * 
 * @return
 * @throws Exception
 */
public String display() throws Exception {
    if (showArchived == null) {
        showArchived = false;
    }
    UserService userService = (UserService) ServiceFactory.getInstance().createService(UserService.class);
    List<List<UserView>> usersForUserGroup = userService.getUsers(oid, showArchived);
    groupMembers = usersForUserGroup.get(0);
    nonGroupMembers = usersForUserGroup.get(1);
    groupMembersJson = serializeToJsonString(groupMembers);
    nonGroupMembersJson = serializeToJsonString(nonGroupMembers);

    return SUCCESS;
}

public String addMembers() throws Exception {
    groupMembers = (List<UserView>) deserializeFromJsonString(groupMembersJson);
    nonGroupMembers = (List<UserView>) deserializeFromJsonString(nonGroupMembersJson);
    UserService userService = (UserService) ServiceFactory.getInstance().createService(UserService.class);
    for (Integer userOid : nonGroupMemberOids) {
        UserView userview = userService.getUser(userOid);
        groupMembers.add(userview);
        for(int i = 0; i< nonGroupMembers.size(); i++){
            UserView view = nonGroupMembers.get(i);
            if(view.getOid().equals(userOid)){
                nonGroupMembers.remove(i);
                break;
            }
        }
    }
    groupMembersJson = serializeToJsonString(groupMembers);
    nonGroupMembersJson = serializeToJsonString(nonGroupMembers);
    return SUCCESS;
}

public String removeMembers() throws Exception {
    groupMembers = (List<UserView>) deserializeFromJsonString(groupMembersJson);
    nonGroupMembers = (List<UserView>) deserializeFromJsonString(nonGroupMembersJson);
    UserService userService = (UserService) ServiceFactory.getInstance().createService(UserService.class);
    for (Integer userOid : groupMemberOids) {
        UserView userview = userService.getUser(userOid);
        nonGroupMembers.add(userview);
        for(int i = 0; i< groupMembers.size(); i++){
            UserView view = groupMembers.get(i);
            if(view.getOid().equals(userOid)){
                groupMembers.remove(i);
                break;
            }
        }
    }
    groupMembersJson = serializeToJsonString(groupMembers);
    nonGroupMembersJson = serializeToJsonString(nonGroupMembers);
    return SUCCESS;
}                                                     

The problem I have is that when I'm moving elements from one List to the other List, I need access to the lists that are currently used in the tables. Because Struts2 actions are stateless, I need to persist these lists between 2 actions.

  • I've tried just having the lists in a <s: hidden /> block, but that can't be converted back easily.
  • My current attempt is by serializing them to JSON through the JSONUtil.serialize and JSONUtil.deserialize methods, but for some reason that deserializes them to List<HashMap> instead of List<T> .
  • I've suggested my coworker we use the Session, but he's concerned about performance losses.

What's the best way to handle this?

Action chaining is the correct way. I am using annotation so code looks like this.

@Action(
            value = "/loginAction",
            results = {
                    @Result(name = "car_user", type="chain", params = {"actionName", "getAllUserAction", "loginUser", "${loginUser}"}),

....................

Where loginUser is the variable having setter getter in loginAction class and the chain attion class which has actionName getAllUserAction will receive it in loginUser Variable in that class which has setter getter for the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM