javaEE之--------统计站点在线人数,安全登录等(观察者设计模式)
整体介绍下:
监听器:监听器-就是一个实现待定接口的普通Java程序,此程序专门用于监听别一个类的方法调用。都是使用观察者设计模式。
小弟刚接触这个,做了些简单的介绍。大神请绕道,技术仅仅是一点点,方便以后遇到问题能够看这些能解决一些问题。同一时候希望和大家一起分享下自己写的小小演示样例
在servlet中事件源:
事件源:HttpSession
HttpSessionListener -
HttpSessionAttributeListener
HttpSessionEvent
事件源:ServletRequest
ServletRequestListenr
ServletRequestAttributeListener
ServletRequestEvent
事件源:ServletContext
ServletContextListener
ServletContextAttributeListener
ServletContextEvent
在我们这个项目中用到知识点:
HttpSessionListener,监听HttpSession的创建和销毁。
sessionCreated
sessionDestroyed
Session的默认有效时间为30分。
能够通过配置的方式改动它的值。
能够调用session.invalidate方法销毁当前Session.
主要作用是记录当前全部在线人数,不管是用户还是游客。·
上面是我们做这个实例用到的知识,以下详细介绍:
实例需求:
1、使用HttpSessionListener记录在线人数。
2、使用HttpSessionAttributeListener记录登录人数。
3、 将用户踢出系统。
一:记录在线人数,我们须要用到HttpSessionListener 观察者设计模式
每个用户訪问站点都会有一个seesion的创建,所以我们从创建session的统计就可以
写一个类,实现HttpSessionListener接口
sessionCreated 函数和 sessionDestroyed
。我们仅仅用到创建sessionCreated
把创建的session所有放在一个map集合中,当前台须要获取的时候,直接从context中获取。进行其它操作。事实上
sessionCreated 用到集合上锁,api自带,解决多线程问题。
public class MySessionListener implements HttpSessionListener { @Override
public void sessionCreated(HttpSessionEvent se) {
//我们把创建的session封装在一个map中
Map<String, HttpSession> map =(Map<String, HttpSession>) se.getSession().getServletContext().getAttribute("onLines");
if(map==null){//说明这是第一次訪问是,须要自己new 一个对象
map=Collections.synchronizedMap(new HashMap<String, HttpSession>());//採用集合上锁。採用java 自带的上锁函数
se.getSession().getServletContext().setAttribute("onLines", map);
}
// System.out.println("listener加入一个了");
map.put(se.getSession().getId(), se.getSession());//以session 的id为key,session对象为value存在map中
} @Override
public void sessionDestroyed(HttpSessionEvent se) {
}}
二,前台显示页面
我们採用登录前后。都在一个页面显示。採用jstl表达式进行差别就能够。
当中。我们用到当登录成功之后。我们就直接採用设置session。让其差别就能够,当我们採用安全登录也是採用这个session里面是都存在值。
<body>
<!-- 需求:做一个能够同意游客訪问。同意登录,能够查看当前用户(包含游客)。
信息-----name,ip,createTime,lastTime,须要一个权限是都能够踢人(使session失效)
就是讲session创建的时候,存一个list中去,然后相关的信息从session中回去就能够 --> <h2>这是用户登录界面</h2> <c:if test="${empty sessionScope.user}" var="boo">
<form action="<c:url value='/LoginServlet'/>" method="post">
NAME:<input type="text" name="name"/><br/>
PWD :<input type="text" name="pwd"/><br/>
<input type="submit" value="提交信息"/>
</form>
</c:if>
<c:if test="${!boo }">
欢迎您。${sessionScope.user.name}
<a href="<c:url value='/servlet/ShowLoginServet'/>" >显示当前訪问数量</a>
<a href="<c:url value='/servlet/LoginoutServlet'/>">退出</a>
</c:if>
<hr/>
<a href="<c:url value='/jsps/show.jsp'/>">这是真有用户能訪问的用户</a>
<a href="<c:url value='/open/open.jsp'/>">游客能訪问的内容</a> </body>
三。登录之后处理
在是否登录,我们简单的模拟下
成功之后我们就设置一个session的值传给前台处理
<span style="font-size:18px;"> public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//接收參数的编码问题已经通过 过滤器设置好
String name=request.getParameter("name");
String pwd =request.getParameter("pwd"); //获得參数之后。開始封装数据
User user =new User();
user.setName(name);
user.setPwd(pwd);
user.setAdmin(true);
//封装数据之后,调用service层。訪问数据库,简单的模拟 当name和pwd相等就推断登录成功
if(name!=null && !name.trim().equals("") && pwd != null && pwd.trim().length()>0 ){
if(name.endsWith(pwd)){//模拟下。相等就是登录成功
request.getSession().setAttribute("user", user);
}
}
response.sendRedirect(request.getContextPath()+"/index.jsp");//重定向到主页
}</span>
四。查看在线用户
<span style="font-size:14px;"> <body>
<h2>这是用户登录拥有的资源</h2>
<!-- 前台最后採用list<map《》>的封装信息 -->
<!-- 显示界面。须要知道session里面的信息,採用监听器 要监听游客,和 用户。採用httpSession-->
欢迎您。 。${user.name }<br/>
<table >
<tr>
<td>姓名</td>
<td>IP</td>
<td>创建时间</td>
<td>近期訪问时间</td>
<td>操作</td>
</tr>
<c:forEach items="${requestScope.list }" var="map">
<tr>
<td>
<c:if test="${ empty map.user }" var="boo">
游客
</c:if>
<c:if test="${!boo }">
${map.user.name }
</c:if>
</td> <td>
${map.ip }
</td> <td>
<fmt:formatDate value="${map.createTime }" pattern="yyyy-MM-dd HH-mm-ss"/>
</td> <td>
<fmt:formatDate value="${map.LastAccessedTime }" pattern="yyyy-MM-dd HH-mm-ss"/> </td> <td>
<c:if test="${!boo && map.user.admin }">
<!-- <a href="<c:url value='/servlet/KitLogin'/>? id=${map.id }&&user=${user.name}">踢人</a> --> <a href="/onlineWeb/servlet/KitLogin?id=${map.id }&&user=${user.name}">踢人</a>
</c:if>
</td> </tr>
</c:forEach> </table> </span>
查看当前用户在线人数。我们直接收集參数:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//在这里。我们须要将前台须要的信息在这里封装 //从onLines《sessionID,session对象中》拿到整个session集合,提取当中的信息
//然后把这个信息封装起来转给前台显示
List<Map<String, Object>> list=new ArrayList<Map<String,Object>>();//採用list装数据
Map<String, HttpSession> onLines=(Map<String, HttpSession>) request.getSession().getServletContext().getAttribute("onLines");
// System.out.println(onLines);
Iterator<Map.Entry<String, HttpSession>> it= onLines.entrySet().iterator();
while(it.hasNext()){
Entry<String, HttpSession> entry=it.next();
HttpSession sess=entry.getValue();//拿到单个的session对象了
Map<String, Object> mm =new HashMap<String, Object>();//採用map封装一行数据,然后放在list 中去。就是一个表的数据
mm.put("id", sess.getId());//获取session的id
mm.put("createTime",new Date(sess.getCreationTime()));//创建的时间.传过去的是date类型我们前台进行解析。显示出来
mm.put("LastAccessedTime", new Date(sess.getLastAccessedTime()));//上次訪问的时间
mm.put("user", sess.getAttribute("user"));
mm.put("ip", sess.getAttribute("ip"));
//前台须要的信息补全,后台去使用
list.add(mm);
}
request.setAttribute("list", list);
request.getRequestDispatcher("/jsps/show.jsp").forward(request, response);//呆着list对象跳转的显示页面
}
效果图:
五。管理员踢人
这里所有设置为管理员。能够在值对象里面改动
主要是在点击踢人时,将该对象的id传过来,踢人就是把用户的session.invalidate,设置同样的username。不能踢。
踢人时,我们不只不过改session。还须要将map对象里面的session移除。
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter pw =response.getWriter();
String id=request.getParameter("id");
String username=request.getParameter("user");//当前页的user
Map<String, HttpSession> map=(Map<String, HttpSession>) request.getServletContext().getAttribute("onLines");
HttpSession se=map.get(id);//通过id 得到session对象
User user= (User) se.getAttribute("user"); //通过session对象能够得到user对象
System.out.println("username传过来的www"+username);
System.out.println("本地直接获得的www"+user.getName());
if(!user.getName().equals(username)){//不能删除和自己同名的用户
if(map.containsKey(id)){
System.out.println("已经删除");
HttpSession ss= map.get(id);
map.remove(id);//从context里面移除
ss.invalidate();//让session失效
pw.write("成功删除用户");
}else{
pw.write("该用户已被删除");
}
request.getRequestDispatcher("/jsps/show.jsp");
}else{
pw.write("用户不能踢自己");
}
pw.write("<a href='/onlineWeb/index.jsp'>返回</a>");
}
六。主动退出
直接将自己的session移除,和把自己的从map中移除
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Map<String, HttpSession> map =(Map<String, HttpSession>) request.getServletContext().getAttribute("onLines");
String id=request.getSession().getId();
map.remove(id);//通过id来删除,context大容器中的session对象
request.getSession().invalidate();
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
七,安全登录
曾经我们写得演示样例。仅仅要正确输入了路径和訪问的项目,我们就能直接訪问,没有安全性可言,可是如今我们能够利用
过滤器来实现这个功能。
我们的根据是我们登录成功之后,我们将session里面设置值,然后我们就能够根据这个来过滤了,当前我们知道,之前的全站压缩和过滤敏感词等,都是须要配置过滤器路径。所以我们在配置路径是须要注意。登录界面和处理登录界面的结果是不能被过滤的。所以一般这两个都是直接放在根文件夹下的。
public class SafeLoginrFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
} @Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse resp=(HttpServletResponse) response;
if(req.getSession().getAttribute("user")==null){//这是过滤非法用户使用的,仅仅有登录的用户才干进入用户权限
resp.sendRedirect(req.getContextPath()+"/index.jsp");
}else{
chain.doFilter(req, resp);
} } @Override
public void destroy() {
}
依据上面的这个,我们能够设置一些文件夹能够让游客訪问。就是不用通过过滤器的页面,单独写一个文件夹都能够。
拦截路径在web.xml中配置:
<filter-mapping>
<filter-name>safeLogin</filter-name>
<url-pattern>/servlet/*</url-pattern>
<url-pattern>/jsps/*</url-pattern>
</filter-mapping>
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
总结:在演示样例中。我们仅仅须要知道。用HttpSessionListener,我们用它能够实现创建了多少session对象了,将他放到一个map容器中,须要的时候取出来即可了。当然,session中也存在非常多有价值的,如id,訪问时间。最后一次訪问时间等。
其余的都是曾经经常使用的知识。
javaEE之--------统计站点在线人数,安全登录等(观察者设计模式)的更多相关文章
- javaEE之-------统计站点刷新量
每一个站点都有自己的统计訪问量,可是少不了server会出现意外情况,(如断电..) 所以就须要我们在站点挂机的前段时间将这个数据存起来. 我们就须要用到站点最大的容器,application,我们採 ...
- springboot使用HttpSessionListener 监听器统计当前在线人数
概括: request.getSession(true):若存在会话则返回该会话,否则新建一个会话. request.getSession(false):若存在会话则返回该会话,否则返回NULL ht ...
- Servlet监听器统计网站在线人数
本节我们利用 Servlet 监听器接口,完成一个统计网站在线人数的案例.当一个用户登录后,显示欢迎信息,同时显示出当前在线人数和用户名单.当用户退出登录或 Session 过期时,从在线用户名单中删 ...
- 【Java EE 学习 20】【使用过滤器实现登陆验证、权限认证】【观察者模式和监听器(使用监听器实现统计在线IP、登录IP 、踢人功能)】
一.使用过滤器实现登录验证.权限认证 1.创建5张表 /*使用过滤器实现权限过滤功能*/ /**创建数据库*/ DROP DATABASE day20; CREATE DATABASE day20; ...
- 文件系统权限引起IIS站点总跳登录页面
今天在IIS上部署一个ASP.NET站点时遇到一个很奇怪的问题,不管访问什么页面,都会跳到登录页面,即使是访问静态文件. 折腾半天,百思不得其解,百整不得其果... 后来突然想到,是不是站点所在文件夹 ...
- 如何在silverlight中以同步方式 获取sharepoint2013站点的当前登录账号
最近有个项目用到了silverlight要同步方式获取当前登录账号.异步的方式无法跟其他应用结合.主要先后顺序问题.但是silverlight非常不好获取到当前登录账号.即使获取到了也是异步方式获取. ...
- 站点接入QQ登录
首先引入授权js文件 <script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/op ...
- vertica时间计算SQL语句实例:统计一天内登录的用户
SQL语句实例: select count(id) as num from public.user where cast((CURRENT_TIMESTAMP-login_timed) day as ...
- javaEE Design Patter(1)初步了解23种常用设计模式
设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. ...
随机推荐
- TCP协议滑动窗口(一)——控制大批量数据传输速率
窗口大小:TCP头中一个16位的域,表示当前可用接受缓冲区大小.在每个TCP对等段连接初始化时,告诉对方自己的窗口大小(不一定是满额,假如满额65201字节,可能暂时通告5840字节).若客户端接受数 ...
- Android项目实战_手机安全卫士程序锁
###1.两个页面切换的实现1. 可以使用Fragment,调用FragmentTransaction的hide和show方法2. 可以使用两个布局,设置visibility的VISIABLE和INV ...
- ionic2/3 禁止屏幕旋转,禁止横屏,竖屏
ionic2/ionic3禁止屏幕旋转,及解除禁止旋转 1.添加插件: cmd到项目目录---> cordova plugin add cordova-plugin-screen-orienta ...
- 超经典~超全的jQuery插件大全
海量的jQuery插件帖,很经典,不知道什么时候开始流传,很早以前就收藏过,为了工作方便还是发了一份放在日志里面. 其中有些已经无法访问,或许是文件移除,或许是被封锁.大家分享的东西,没什么特别的可说 ...
- ajax 实现输入提示效果
网站主页 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- 15、Scala隐式转换和隐式参数
1.隐式转换 2.使用隐式转换加强现有类型 3.隐式转换函数的作用域与导入 4.隐式转换发生时机 5.隐式参数 1.隐式转换 要实现隐式转换,只要程序可见的范围内定义隐式转换函数即可.Scala会自动 ...
- Lazarus Reading XML- with TXMLDocument and TDOMNode
这里读取'HistoryPath' ,'TracePath' 元素下的‘value’属性使用的是 var xmlCfg: TXMLDocument; .... function ReadXMLCFG: ...
- IOS7 APP 升级的10个TIP 建议
There is no way to preserve the iOS 6 style status bar layout. The status bar will always overlap yo ...
- 解决fixed在苹果手机抖动问题/头部底部固定布局
1.头部和底部固定,中间内容滚动,不涉及fixed 1)absolute与height:100% <!DOCTYPE html><html><head> <m ...
- S3C2440时钟体系
注:以下内容学习于韦东山老师arm裸机第一期视频教程 一. 2440时钟简介 1.1 2440是一个SOC(system on chip)系统,不仅有很多CPU,还有很多外设,在2440芯片手册有系统 ...