java에서session 감청을 사용하여 같은 계정 로그인 제한, 로그인 인원 제한 실현
문제 도메인:
1. 같은 계정 로그인: 이 계정이 로그인되어 있으면 다시 로그인할 수 없습니다(QQ 모드와 반대).
2. 로그인 인원수 제한, 초과, 도달 인원수 제한은 시스템이 바쁘니 잠시 후에 다시 시도하십시오.
해결 방법: HttpSessionAttributeListener 모니터를 사용합니다(제가 HttpSessionListener를 동시에 사용했지만 조작이 잘 안 되는 것 같습니다).
지식 비축: HttpSessionAttributeListener에attributeAdd,attributeRemove,attributeReplace 세 가지 방법이 있습니다.
세션의 setAttribute,removeAttribute는attributeAdd,attributeRemove 방법을 터치하고, 같은 세션의 같은attribute를 중복 설정하면attributeReplace 방법을 터치합니다.
HttpSessionListener가 잘 작동하지 않는 이유: jsp 페이지에 접근하기만 하면session(html에 접근하면 session을 만들지 않습니다. 서버 쪽에서, 예를 들어 servlet에서 HttpServletRequest.getSession(true)을 호출해야 만들 수 있습니다), jsp는 동적 페이지입니다. 본질은 servlet입니다.내 로그인.jsp는 분명히 jsp입니다. 제가 감청기에서 invalidate에session을 하나 가지고 로그인 페이지로 돌아오면 바로 session을 하나 더 만들 수 있습니다.이것은 내가 잘 느끼지 못하는 곳이어서 시간이 집에 도착하지 않았다.
구현:
감청기 코드
public class OnlineListener implements HttpSessionListener,
HttpSessionAttributeListener {
private static List<SessionAndUser> sessions;
static int delS = -1;
static boolean flag = false;
static {
if (sessions == null) {
sessions = Collections
.synchronizedList(new ArrayList<SessionAndUser>());
}
}
public void sessionCreated(HttpSessionEvent hse) {
System.out.println(hse.getSession() + "-" + new Date());
System.out.println(hse.getSession() + "-" + new Date());
}
public void sessionDestroyed(HttpSessionEvent hse) {
System.out.println("-------------sessionDestroyed()-----------");
System.out.println(hse.getSession() + " "
+ new Date(hse.getSession().getLastAccessedTime()));
System.out.println(hse.getSession() + " " + new Date());
}
public void attributeAdded(HttpSessionBindingEvent e) {
System.out.println("-------------*start added*-----------------------"
+ sessions.size());
HttpSession session = e.getSession();
ActionContext ctx = ActionContext.getContext();
boolean newOne = true;
String attrName = e.getName();
//
if (attrName.equals(Constant.USER_NAME)) {
//
if (sessions.size() >= Constant.USER_LIMIT) {
newOne = false;
ctx.put("timeoutMSG", "serverBusy");
}
String nowUser = (String) e.getValue();
// session, ,
for (int i = sessions.size() - 1; i >= 0; i--) {
SessionAndUser tem = sessions.get(i);
if (tem.getUserName().equals(nowUser)) {
newOne = false;
ctx.put("timeoutMSG", "beenLoged");// tem.getSession().invalidate();//
// , remove
break;
}
}
//
if (newOne) {
SessionAndUser sau = new SessionAndUser();
sau.setUserName(nowUser);
sau.setSession(session);
sau.setSid(session.getId());
sessions.add(sau);
}
}
}
public void attributeRemoved(HttpSessionBindingEvent e)
throws IllegalStateException {
HttpSession session = e.getSession();
System.out
.println("-------------*start Removed*-----------------------"
+ sessions.size());
if (delS > -1) {
if (flag) {
sessions.remove(delS);
flag = false;
}
} else {
//
String attrName = e.getName();
if (attrName.equals(Constant.USER_NAME)) {
String nowUser = (String) e.getValue();
// session
for (int i = sessions.size() - 1; i >= 0; i--) {
SessionAndUser tem = sessions.get(i);
if (tem.getUserName().equals(nowUser)) {
sessions.remove(i);
break;
}
}
}
}
}
public void attributeReplaced(HttpSessionBindingEvent e) {
HttpSession session = e.getSession();
System.out
.println("-------------*start replace*-----------------------"
+ sessions.size());
String attrName = e.getName();
delS = -1;
//
if (attrName.equals(Constant.USER_NAME)) {
// User nowUser = (User) e.getValue();//old value
String nowUser = (String) session.getAttribute(Constant.USER_NAME);// session user
// session
for (int i = sessions.size() - 1; i >= 0; i--) {
SessionAndUser tem = sessions.get(i);
if (tem.getUserName().equals(nowUser)
&& !tem.getSid().equals(session.getId())) {
System.out.println("Remove:invalidate 1!");
delS = i;
flag = true;
} else if (tem.getSid().equals(session.getId())) {
tem.setUserName(nowUser);
}
}
if (delS != -1) {
sessions.get(delS).getSession().invalidate();// remove 。 sessions
}
}
}
}
코드의 주요 사고방식은 정적 목록 < Session And User > 저장session과 계정 이름을 정의하는 것이다.로그인한 Action에서 감청기 반환값 및 처리 코드 얻기
session.setAttribute(Constant.USER_NAME, operator.getUsername());
ActionContext ctx = ActionContext.getContext();
if("serverBusy".equals(ctx.get("timeoutMSG"))){
ctx.put("timeoutMSG", " , ");
return "jump";
}
if("beenLoged".equals(ctx.get("timeoutMSG"))){
ctx.put("timeoutMSG", " ");
return "jump";
}
페이지 캡처 프롬프트 코드
<%@taglib prefix="s" uri="/struts-tags"%>
<s:property value="#attr.timeoutMSG" />
읽어주셔서 감사합니다. 여러분에게 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JWT로 세션을 관리하지 마십시오.세상에는 JWT(JOSE/JWS/JWE)로 세션 관리를 해서는 안 된다는 기사가 2017년부터 산 정도 있는데 왠지 JWT에서 세션 관리를 하려고 하는 사람이 있다. 번역 기사이거나 암호의 설명이 너무 길거나 해서,...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.