egovframework의 EgovHttpSessionBindingListener 클래스와 EgovMultiLoginPreventor 클래스로 중복 로그인 방지를 구현하던 중,
java.lang.illegalargumentexception setattribute non-serializable attribute ***에러가 발생했다.
session에 저장하기 위해선 해당 클래스 Serializable 클래스를 상속해 줘야 하는데, VO는 이미 상속이 되어 있었다.
VO 말고도 EgovHttpSessionBindingListener, EgovMultiLoginPreventor역시 Serializable 클래스를 상속해줘야 한다.
egov도 버젼 코드에 실수가 존재하나보다.
EgovHttpSessionBindingListener.java
package egovframework.com.utl.slm;
import java.io.Serializable;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Class Name : EgovHttpSessionBindingListener.java
* @Description : 중복 로그인 방지를 위해 사용자의 로그인 아이디와 세션을 제어하는 구현 클래스
* @Modification Information
*
* 수정일 수정자 수정내용 ------- ------- ------------------- 2014.09.30 표준프레임워크 최초생성
* @author YJ Kwon
* @since 2014.09.30
* @version 3.5
*/
public class EgovHttpSessionBindingListener implements HttpSessionBindingListener, Serializable {
private static final long serialVersionUID = -6535453381287200501L;
private static Logger logger = LoggerFactory.getLogger(EgovMultiLoginPreventor.class);
/**
* 사용자의 로그인 세션에 EgovHttpSessionBindingListener가 바인딩될 때 자동 호출되는 메소드로, 사용자 세션이 이미 존재하는지를 검사하여 하나의
* 어플리케이션 내에서 하나의 세션만 유지되도록 한다
*/
public void valueBound(HttpSessionBindingEvent event) {
logger.error("\n\t!! VALUE BOUND !!");
if (EgovMultiLoginPreventor.findByLoginId(event.getName())) {
EgovMultiLoginPreventor.invalidateByLoginId(event.getName());
}
EgovMultiLoginPreventor.loginUsers.put(event.getName(), event.getSession());
}
/**
*
* 로그아웃 혹은 세션타임아웃 설정에 따라 사용자 세션으로부터 EgovHttpSessionBindingListener가 제거될 때 자동 호출되는 메소드로, 사용자의 로그인
* 아이디에 해당하는 세션을 ConcurrentHashMap에서 모두 제거한다
*/
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
logger.error("\n\t!! VALUE UNBOUND !!");
EgovMultiLoginPreventor.loginUsers.remove(event.getName(), event.getSession());
}
}
EgovMultiLoginPreventor.java
package egovframework.com.utl.slm;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Class Name : EgovMultiLoginPreventor.java
* @Description : 중복 로그인 방지를 위해 사용자의 로그인 아이디와 세션 아이디를 관리하는 구현 클래스
* @Modification Information
*
* 수정일 수정자 수정내용 ------- ------- ------------------- 2014.09.30 표준프레임워크 최초생성
* @author YJ Kwon
* @since 2014.09.30
* @version 3.5
*/
public class EgovMultiLoginPreventor implements Serializable {
private static final long serialVersionUID = 4012190701164146206L;
private static Logger logger = LoggerFactory.getLogger(EgovMultiLoginPreventor.class);
public static ConcurrentHashMap<String, HttpSession> loginUsers =
new ConcurrentHashMap<String, HttpSession>();
/**
* 사용자의 로그인 아이디로 생성된 세션이 있는지를 확인한다
*/
public static boolean findByLoginId(String loginId) {
logger.error("\n\t>> loginUsers id : {} <<", loginId);
return loginUsers.containsKey(loginId);
}
/**
* 사용자의 로그인 아이디로 이미 존재하는 세션을 무효화한다
*/
public static void invalidateByLoginId(String loginId) {
Enumeration<String> e = loginUsers.keys();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
logger.error("\n\t>> session key : {} <<", e.toString());
if (key.equals(loginId)) {
logger.error("\n\t:: SESSION INVALIDATE {} <<", loginId);
loginUsers.get(key).invalidate();
}
}
}
}