servlet第六讲
(一)ServletContext的讲解和使用
什么是ServletContex?
可以想象其为一个公用空间,可以被所有的客户访问
如何使用ServletContext?
1.得到ServletContext
this.getServletContext();
2.可将其看做一张表,其与sesseion相似:每一行就为一个属性
----------------------------------------
| 名字(String)| 值(Object)|
----------------------------------------
| | |-------->属性1
----------------------------------------
| | |
----------------------------------------
| | |
----------------------------------------
操作
添加属性:setAttribute(String name,Object ob);
得到值: getAttribute(String)返回Object
删除属性:removeAttribute(String name)
示例——添加servletContext属性
public void process(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException{ //业务逻辑 try{ //中文乱码 res.setContentType("text/html;charset=UTF-8"); PrintWriter pw=res.getWriter(); //1.得到ServletContext ServletContext sc=this.getServletContext(); //2.添加属性 sc.setAttribute("myInfo","我是邓龙"); pw.println("给servletContext中添加一个属性MyInfo
"); //比较session,添加属性 HttpSession hs=req.getSession(true); hs.setAttribute("test","中国人"); hs.setMaxInactiveInterval(60*3); pw.println("向session中添加一个test属性 他的值是中国人"); }catch(Exception ex){ ex.printStackTrace(); } }
示例——从servletContext中得到属性
public class ServletContextTest2 extends HttpServlet { public void process(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException{ //业务逻辑 try{ //中文乱码 res.setContentType("text/html;charset=UTF-8"); PrintWriter pw=res.getWriter(); //1.得到servletContext ServletContext sc=this.getServletContext(); //2.得到属性和它对应的值 String info=(String)sc.getAttribute("myInfo"); pw.println("从servletContext中得到属性myInfo对应的值为我是邓龙
"); //比较sesseion,取出属性值 HttpSession hs=req.getSession(true); String val=(String)hs.getAttribute("test"); pw.println("session中的test="+val+"
"); }catch(Exception ex){ ex.printStackTrace(); } }
3.生命周期
ServletContext中的属性的生命周期从创建开始,到服务器关闭而
结束
注意事项:
因为存在ServletContext中的数据会长时间的保存在服务器,会占
用内存,因此我们建议不要想serveltContext中添加过大的数据
(二)servlet中如何操作文件
因为serlvet本来就是一个.java文件,因此,其同普通java文件操作
文件是一样的
示例——读取文件内容
public class ServletFileTest1 extends HttpServlet { public void process(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException{ //业务逻辑 try{ //中文乱码 res.setContentType("text/html;charset=UTF-8"); PrintWriter pw=res.getWriter(); //创建一个FileReader FileReader fr=new FileReader("D://myCounter.txt"); BufferedReader br=new BufferedReader(fr); //读出一行数据 String numVal=br.readLine(); br.close();//一定关闭文件流 pw.println("从文件中取出的数据是:"+numVal); }catch(Exception ex){ ex.printStackTrace(); } }
示例——把内容写入文件
public void process(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException{ //业务逻辑 try{ //中文乱码 res.setContentType("text/html;charset=UTF-8"); PrintWriter pw=res.getWriter(); //创建一个FileWriter,看 内存数据 ——>磁盘文件(称之为写入,也即输出流) //看 磁盘文件 ——>内存数据(称之为读入,也即输入流) FileWriter fw=new FileWriter("D://myCounter.txt"); BufferedWriter bw=new BufferedWriter(fw); //在文件写入数据 bw.write("我写东西"); bw.close();//关闭文件流 pw.println("在文件中写入了数据"); }catch(Exception ex){ ex.printStackTrace(); } }
(三)增加网站计数器
在网站开发中,有很多功能需要使用ServletContext,比如:
1.网站计数器
2.网站在线用户的显示
3.简单的聊天系统
··················
总之,如果是涉及到不用用户共享数据,而这些数据量不大,同时
又不希望写入数据库中,我们就可以考虑使用ServletContext来实
现
有效点击:
1.只要访问过该网页就算一次,刷新也算一次,有点假
2.不同的ip访问,算一次;如果同一个ip在一定时间(如一天),
不管浏览该网页多少次都算一次
3.用户推出网站,再次访问页算一次
实现方案:
1.当某个用户访问该网页时,就在该数据库中增加一次(比如有一
张统计表)
缺点:对数据库访问太频繁,服务器压力太大
优点:很好理解,也好实现
2.设置一个静态变量,当服务器启动时,可以通过文件或表初始化
该变量;当服务器关闭时,再将变量的值写入到文件或是数据库中
缺点:实现复杂,要求对文件操作
优点:效率高,不会频繁的访问文件或数据库
3.使用ServletContext,它的实现与第二种相似
实现网站计数器:
1.在Wel.java中操作ServletContext,每刷新一次算一次
2.在LoginCl.java中操作ServletContext,用户每成功登陆一次算
一次
3.对2方法的优化改进(减少对文件的操作)
各个用户每登陆一次,就要去操作一个文件,这样效率低下,可不
可以减少对文件的操作次数:
在Servlet的生命周期中——
可以在init()方法中初始化servletContext中属性times对应的初始值
可以在destroy()方法中,一次性的将serveletcontext中属性times
对应的值写入文件中
代码实现:
在LoginCl.java中:
1.重写init()方法
//重写init()函数 public void init() throws ServletException{ try{ //只会被调用一次 System.out.println("init被调用"); //========添加网页访问次数的功能(读取部分)=========== //用户成功登陆一次就计算一次 FileReader fr=new FileReader("D://myCounter.txt"); BufferedReader br=new BufferedReader(fr); String numVal=br.readLine(); br.close(); //将times值放入到servletContext中 this.getServletContext().setAttribute("visitTimes",numVal); //========添加网页访问次数的功能(读取部分)=========== }catch(Exception ex){ ex.printStackTrace(); } }
2.在process()方法中添加计数功能
//========添加网页访问次数功能(计算部分)========= //将ServletContext中的visitTime所对应的值++ String times=this.getServletContext().getAttribute("visitTimes").toString(); //对times的值++再重新写回servletContext this.getServletContext().setAttribute("visitTimes",(Integer.parseInt(times)+1)); //========添加网页访问次数功能(计算部分)=========
3.重写destroy()方法
public void destroy() { try{ System.out.println("destroy被调用"); //========添加网页访问次数的功能(写入部分)=========== //再将新的次数写回文件 FileWriter fw=new FileWriter("D://myCounter.txt"); BufferedWriter bw=new BufferedWriter(fw); bw.write(this.getServletContext().getAttribute("visitTimes").toString()); bw.close();//关闭文件流 //========添加网页访问次数的功能(写入部分)=========== }catch(Exception ex){ ex.printStackTrace(); } }
4.在页面显示(Wel.java)
//显示网页访问次数 pw.println("该网页被访问了"+this.getServletContext().getAttribute("visitTimes").toString()+"次
"); //显示主机IP地址 pw.println("您的IP地址="+req.getRemoteAddr()+"
"); //显示主机名 pw.println("你的主机名="+req.getRemoteHost()+"
"); pw.println("
");