简体   繁体   中英

Spring MVC @Sessionattributes issue in multiple browser tabs

We are using latest version of spring. .

We are uding @Sessionattributes of spring mvc to stote data in session scope..

The problem is it not working as expected when we are working with multiple tabs of the browser. .

We have a search page that allows the use to search the database using multiple fields..We are storing the results in session using @Sessionattributes.

Problem: For example user gives some input and searches and results are stored in session with name "searchresults".

If the user opens the new tab and searches using the different criteria again search results will be stored in session with name "searchresults"..

So if user reloads the first tab...he will se search results whatever there in second tab..

So..:searchresults" in session will have results from second tab...so even if user refresh first tab..he will see results he got using the second tab..

Is there any solution for this spring mvc...

Yeps, as lewthor says multiple tabs share a session.

One way to deal with the situation is to have a tab specific url component that will be included in the session key. If you are on a product listing page, and you're opening a new tab per product, if you make sure that the urls upon tab opening are different eg by using product id in the url /product/{product.id} , all you have to do make the proper behaviour is append the id to session key searchresults{product.id}

There is also a @SessionAttribute centric solution, a customization that serves just this purpose, descibed in the blog here and based on the older blog described here . The solution implements a CustomSessionAttributeStore, and maintaines a Map of Maps where the inner Map is the deafult SessionAttributes, identified by the conversation id (in your case the tab id)

public class ConversationalSessionAttributeStore implements SessionAttributeStore, InitializingBean {

  @Inject
  private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
  private Logger logger = Logger.getLogger(ConversationalSessionAttributeStore.class.getName());

  private int keepAliveConversations = 10;

  public final static String CID_FIELD = "_cid";
  public final static String SESSION_MAP = "sessionConversationMap";

  @Override
  public void storeAttribute(WebRequest request, String attributeName, Object attributeValue) {
    Assert.notNull(request, "WebRequest must not be null");
    Assert.notNull(attributeName, "Attribute name must not be null");
    Assert.notNull(attributeValue, "Attribute value must not be null");

    String cId = getConversationId(request);
    if (cId == null || cId.trim().length() == 0) {
      cId = UUID.randomUUID().toString();
      request.setAttribute(CID_FIELD, cId, WebRequest.SCOPE_REQUEST);
    }

    logger.debug("storeAttribute - storing bean reference for (" + attributeName + ").");
    store(request, attributeName, attributeValue, cId);
  }

  private String getConversationId(WebRequest request) {
    return request.getParameter(CID_FIELD);
  }
}

The whole project is posted on GitHub

This happens because browsers treat separate tabs as the same session. You can confirm this by using the browser's dev tools to examine the session cookies that are sent from the two different tabs - they will be the same.

Therefore, Spring rightly treats all of the requests from the different tabs as the same session. If you want your users to be able to conduct separate searches in different tabs, you will have to manage the search results in some way other than session attributes.

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