使用Hibernate和Spring 2.5的并发会话问题

时间:2016-07-08 04:28:03

标签: spring hibernate spring-mvc session spring-security

我正在使用Spring 2.5.6,Spring Security 2.0.4和Hibernate 3.2.6开发一个应用程序。在我的应用程序中,用户可以同时使用相同的凭据从不同的浏览器登录。可以选择更改用户的电子邮件ID。处理此请求的控制器如下: -

@RequestMapping(value="/changeEmail", method= RequestMethod.POST)
public void changeEmail(HttpServletRequest request, HttpServletResponse response, Principal principal) throws IOException
{
    System.out.println("We got the Request");
    boolean hasError = false;
    String currentEmail = request.getParameter("currentEmail");
    String newEmail = request.getParameter("newEmail");
    String confirmEmail = request.getParameter("confirmEmail");
    String password = request.getParameter("password");
    System.out.println("Old Email = " + currentEmail + ", New Email = " + newEmail + ", Confirm Email = " + confirmEmail + ", Password = " + password);
    Map<String, String> errorsMap = new HashMap<String,String>();
    UserFormResponse callBackResponse = new UserFormResponse("",errorsMap);
    if(currentEmail == null || currentEmail.equals(""))
    {
        hasError = true;
        errorsMap.put("currentEmail", "Enter Your Current Email");
    }
    if(newEmail == null || newEmail.equals(""))
    {
        hasError = true;
        errorsMap.put("newEmail", "Enter Your New Email");
    }
    if(confirmEmail == null || confirmEmail.equals("") || !confirmEmail.equals(newEmail))
    {
        hasError = true;
        errorsMap.put("confirmEmail", "Confirm Your Email");
    }
    if(password == null || password.equals(""))
    {
        hasError = true;
        errorsMap.put("password", "Enter Your Password");
    }
    if(!hasError)
    {

        System.out.print("Should be printed : " + callBackResponse.getStatus());
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        Object myUser = (auth != null) ? auth.getPrincipal() :  null;
        if (myUser instanceof User) {
            User user = (User) myUser;
            if(!user.getPassword().equals(password))
            {
                callBackResponse.setStatus("Wrong Password");
                errorsMap.put("password", "Enter Correct Password");
            }
            else if(!user.getUserEmail().equals(currentEmail))
            {
                callBackResponse.setStatus("Wrong Email");
                errorsMap.put("currentEmail", "Enter Your Current Email");
            }
            else
            {
                user.setUserEmail(newEmail);
                getHibernateTemplate().update(user);
                callBackResponse.setStatus("Success");
            }
        }
        else
        {
            callBackResponse.setStatus("You must be logged in");
        }
    }
    else
    {
        callBackResponse.setStatus("Kindly fill all fields");           
    }
    callBackResponse.setErrorsMap(errorsMap);
    System.out.println(callBackResponse.getStatus());
    System.out.println(callBackResponse.getErrorsMap());
    objectMapper.writeValue(response.getOutputStream(),callBackResponse);
}

当我从后端检查数据库时,电子邮件正在被完美更改。但主要问题是,如果用户有两个并发会话,则在一个会话中更改的电子邮件未反映在其他会话中,直到其他会话未被无效。是否有任何解决方案,以便一个会话期间的更改可以反映到另一个并发会话?

注意:请不要建议更改spring和hibernate的版本,因为在Spring 2.5.6中开发此应用程序是必须的。

1 个答案:

答案 0 :(得分:0)

首先在web.xml中定义HttpSessionEventPublisher

<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

然后在spring security.xml文件中定义<session-management>

现在,在控制器方法中使用SessionRegistry使所有会话无效。下面的代码检索所有活动的会话。

List<SessionInformation> activeSessions = new ArrayList<SessionInformation>();
    for (Object principal : sessionRegistry.getAllPrincipals()) {
        for (SessionInformation session : sessionRegistry.getAllSessions(principal, false)) {
            activeSessions.add(session);
        }
    }

在每个活动会话中,您可以调用expireNow()方法使其失效或无效。