博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java web session management
阅读量:5878 次
发布时间:2019-06-19

本文共 8342 字,大约阅读时间需要 27 分钟。

  hot3.png

1 How to find HttpSession by jsessionid?

You need to collect them all in a using a yourself.

public class HttpSessionCollector implements HttpSessionListener {    private static final Map
sessions = new HashMap
(); @Override public void sessionCreated(HttpSessionEvent event) { HttpSession session = event.getSession(); sessions.put(session.getId(), session); } @Override public void sessionDestroyed(HttpSessionEvent event) { sessions.remove(event.getSession().getId()); } public static HttpSession find(String sessionId) { return sessions.get(sessionId); }}

Just register it in web.xml as follows to run it:

com.example.HttpSessionCollector

Then, anywhere you want just do HttpSessionCollector.find(sessionId) to get the HttpSession in question.

 

You need to collect them all in a using a yourself.

public class HttpSessionCollector implements HttpSessionListener {    private static final Map
sessions = new HashMap
(); @Override public void sessionCreated(HttpSessionEvent event) { HttpSession session = event.getSession(); sessions.put(session.getId(), session); } @Override public void sessionDestroyed(HttpSessionEvent event) { sessions.remove(event.getSession().getId()); } public static HttpSession find(String sessionId) { return sessions.get(sessionId); }}

Just register it in web.xml as follows to run it:

com.example.HttpSessionCollector

Then, anywhere you want just do HttpSessionCollector.find(sessionId) to get the HttpSession in question.


That said, this is a huge smell. There are certainly better ways to solve the actual functional requirement than this ;) As I commented in your :

This is the 2nd time that you asked a question which in real world should never be practiced. Honestly said, this all smells. What is it, the problem for which you think that getting the HttpSession associated with JSESSONID in server side and getting the JSESSIONID value in client side is "the" solution? Elaborate about this in a new question, you'll get answers how to do it the right way.

Take it serious. We're not teasing you, we're just trying to help you in the right direction to avoid that your project/webapp will break due to security holes and bad practices and/or that you will get fired.

2 How to find number of active sessions per IP?

The standard Servlet API doesn't offer facilities for that. Best what you can do is to maintain a yourself (where the String is the IP address) with and check on every if the and add it to the Map along with . Then you can get the amount of IP addresses with an active session using on . You only need to ensure that you remove the HttpSession from the Map during .

This all can be done in a single Listener implementing the , and .

public class SessionCounter implements ServletContextListener, HttpSessionListener, ServletRequestListener {    private static final String ATTRIBUTE_NAME = "com.example.SessionCounter";    private Map
sessions = new ConcurrentHashMap
(); @Override public void contextInitialized(ServletContextEvent event) { event.getServletContext().setAttribute(ATTRIBUTE_NAME, this); } @Override public void requestInitialized(ServletRequestEvent event) { HttpServletRequest request = (HttpServletRequest) event.getServletRequest(); HttpSession session = request.getSession(); if (session.isNew()) { sessions.put(session, request.getRemoteAddr()); } } @Override public void sessionDestroyed(HttpSessionEvent event) { sessions.remove(event.getSession()); } @Override public void sessionCreated(HttpSessionEvent event) { // NOOP. Useless since we can't obtain IP here. } @Override public void requestDestroyed(ServletRequestEvent event) { // NOOP. No logic needed. } @Override public void contextDestroyed(ServletContextEvent event) { // NOOP. No logic needed. Maybe some future cleanup? } public static SessionCounter getInstance(ServletContext context) { return (SessionCounter) context.getAttribute(ATTRIBUTE_NAME); } public int getCount(String remoteAddr) { return Collections.frequency(sessions.values(), remoteAddr); }}

Define it in web.xml like follows:

com.example.SessionCounter

You can use it in any servlet like follows:

SessionCounter counter = SessionCounter.getInstance(getServletContext());int count = counter.getCount("127.0.0.1");

3 How to check Who's Online?

You need to collect all logged in users in a Set<User> in the application scope. Just hook on login and logout and add and remove the User accordingly. Basically:

public void login(User user) {    // Do your business thing and then    logins.add(user);}public void logout(User user) {    // Do your business thing and then    logins.remove(user);}

If you're storing the logged-in users in the session, then you'd like to add another hook on session destroy to issue a logout on any logged-in user. I am not sure about how Grails fits in the picture, but talking in Java Servlet API, you'd like to use for this.

public void sessionDestroyed(HttpSessionEvent event) {    User user = (User) event.getSession().getAttribute("user");    if (user != null) {        Set
logins = (Set
) event.getSession().getServletContext().getAttribute("logins"); logins.remove(user); }}

You can also just let the User model implement . The implemented methods will be invoked automagically whenever the User instance is been put in session or removed from it (which would also happen on session destroy).

public class User implements HttpSessionBindingListener {    @Override    public void valueBound(HttpSessionBindingEvent event) {        Set
logins = (Set
) event.getSession().getServletContext().getAttribute("logins"); logins.add(this); } @Override public void valueUnbound(HttpSessionBindingEvent event) { Set
logins = (Set
) event.getSession().getServletContext().getAttribute("logins"); logins.remove(this); } // @Override equals() and hashCode() as well!}

4 How to invalidate another session when a user is logged in twice?

The DB-independent approach would be to let the User have a static Map<User, HttpSession> variable and implement (and and ). This way your webapp will still function after an unforeseen crash which may cause that the DB values don't get updated (you can of course create a ServletContextListener which resets the DB on webapp startup, but that's only more and more work).

Here's how the User should look like:

public class User implements HttpSessionBindingListener {    // All logins.    private static Map
logins = new ConcurrentHashMap<>(); // Normal properties. private Long id; private String username; // Etc.. Of course with public getters+setters. @Override public boolean equals(Object other) { return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this); } @Override public int hashCode() { return (id != null) ? (this.getClass().hashCode() + id.hashCode()) : super.hashCode(); } @Override public void valueBound(HttpSessionBindingEvent event) { HttpSession session = logins.remove(this); if (session != null) { session.invalidate(); } logins.put(this, event.getSession()); } @Override public void valueUnbound(HttpSessionBindingEvent event) { logins.remove(this); }}

When you login the User as follows:

User user = userDAO.find(username, password);if (user != null) {    sessionMap.put("user", user);} else {    // Show error.}

then it will invoke the valueBound() which will remove any previously logged in user from the logins map and invalidate the session.

When you logout the User as follows:

sessionMap.remove("user");

or when the session is timed out, then the valueUnbound() will be invoked which removes the user from the logins map.

转载于:https://my.oschina.net/ChiLin/blog/694188

你可能感兴趣的文章
[译] 感受 4px 基线网格带来的便利
查看>>
oracle常用函数
查看>>
MYBATIS
查看>>
详解消息队列的设计与使用
查看>>
iOS 项目优化
查看>>
筛选出sql 查询结果中 不包含某个字符
查看>>
8进制与16进制
查看>>
使用Sqoop从mysql向hdfs或者hive导入数据时出现的一些错误
查看>>
mybatis:Invalid bound statement (not found)
查看>>
电脑中毒的现象
查看>>
django表单操作之django.forms
查看>>
ZipOutputStream出现多层目录问题
查看>>
webSocket vnc rfb
查看>>
列表推导式 生成器表达式
查看>>
控制子窗口的高度
查看>>
Linux 防火墙iptables命令详解
查看>>
打造笔记本电脑基地重庆要当全球“老大”
查看>>
处理 Oracle SQL in 超过1000 的解决方案
查看>>
《JAVA与模式》之简单工厂模式
查看>>
Alpha线性混合实现半透明效果
查看>>